<?xml version="1.0" encoding="utf-8"?>
<!--
                                                                                     
 h       t     t                ::       /     /                     t             / 
 h       t     t                ::      //    //                     t            // 
 h     ttttt ttttt ppppp sssss         //    //  y   y       sssss ttttt         //  
 hhhh    t     t   p   p s            //    //   y   y       s       t          //   
 h  hh   t     t   ppppp sssss       //    //    yyyyy       sssss   t         //    
 h   h   t     t   p         s  ::   /     /         y  ..       s   t    ..   /     
 h   h   t     t   p     sssss  ::   /     /     yyyyy  ..   sssss   t    ..   /     
                                                                                     
	<https://y.st./>
	Copyright © 2017 Alex Yst <mailto:copyright@y.st>

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <https://www.gnu.org./licenses/>.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<base href="https://y.st./en/coursework/CS1103/" />
		<title>Learning Journal &lt;https://y.st./en/coursework/CS1103/&gt;</title>
		<link rel="icon" type="image/png" href="/link/CC_BY-SA_4.0/y.st./icon.png" />
		<link rel="stylesheet" type="text/css" href="/link/basic.css" />
		<link rel="stylesheet" type="text/css" href="/link/site-specific.css" />
		<script type="text/javascript" src="/script/javascript.js" />
		<meta name="viewport" content="width=device-width" />
	</head>
	<body>
		<nav>
			<p>
				<a href="/en/">Home</a> |
				<a href="/en/a/about.xhtml">About</a> |
				<a href="/en/a/contact.xhtml">Contact</a> |
				<a href="/a/canary.txt">Canary</a> |
				<a href="/en/URI_research/"><abbr title="Uniform Resource Identifier">URI</abbr> research</a> |
				<a href="/en/opinion/">Opinions</a> |
				<a href="/en/coursework/">Coursework</a> |
				<a href="/en/law/">Law</a> |
				<a href="/en/a/links.xhtml">Links</a> |
				<a href="/en/coursework/CS1103/index.xhtml.asc">{this page}.asc</a>
			</p>
			<hr/>
			<p>
				<a href="/en/coursework/BUS1101/" title="Principles of Business Management">BUS 1101</a> |
				<span class="hyperlink_unavailable" title="Basic Accounting">BUS 1102</span> |
				<span class="hyperlink_unavailable" title="Principles of Marketing">BUS 2201</span> |
				<span class="hyperlink_unavailable" title="Multinational Management">BUS 2207</span> |
				<span class="hyperlink_unavailable" title="Business and Society">BUS 3306</span> |
				<a href="/en/coursework/CS1101/" title="Programming Fundamentals">CS 1101</a> |
				<a href="/en/coursework/CS1102/" title="Programming 1">CS 1102</a> |
				<a href="/en/coursework/CS1103/" title="Programming 2">CS 1103</a> |
				<span class="hyperlink_unavailable" title="Computer Systems">CS 1104</span> |
				<a href="/en/coursework/CS2203/" title="Databases 1">CS 2203</a> |
				<span class="hyperlink_unavailable" title="Communications and Networking">CS 2204</span> |
				<a href="/en/coursework/CS2205/" title="Web Programming 1">CS 2205</a> |
				<a href="/en/coursework/CS2301/" title="Operating Systems 1">CS 2301</a> |
				<span class="hyperlink_unavailable" title="Software Engineering 1">CS 2401</span> |
				<span class="hyperlink_unavailable" title="Data Structures">CS 3303</span> |
				<span class="hyperlink_unavailable" title="Analysis of Algorithms">CS 3304</span> |
				<span class="hyperlink_unavailable" title="Web Programming 2">CS 3305</span> |
				<span class="hyperlink_unavailable" title="Databases 2">CS 3306</span> |
				<span class="hyperlink_unavailable" title="Operating Systems 2">CS 3307</span> |
				<span class="hyperlink_unavailable" title="Information Retrieval">CS 3308</span> |
				<span class="hyperlink_unavailable" title="Comparative Programming Languages">CS 4402</span> |
				<span class="hyperlink_unavailable" title="Software Engineering 2">CS 4403</span> |
				<span class="hyperlink_unavailable" title="Advanced Networking and Data Security">CS 4404</span> |
				<span class="hyperlink_unavailable" title="Mobile Applications">CS 4405</span> |
				<span class="hyperlink_unavailable" title="Computer Graphics">CS 4406</span> |
				<span class="hyperlink_unavailable" title="Data Mining and Machine Learning">CS 4407</span> |
				<span class="hyperlink_unavailable" title="Artificial Intelligence">CS 4408</span> |
				<span class="hyperlink_unavailable" title="English Composition 2">ENGL 1102</span> |
				<span class="hyperlink_unavailable" title="World Literature">ENGL 1405</span> |
				<span class="hyperlink_unavailable" title="Introduction to Environmental Science">ENVS 1301</span> |
				<a href="/en/coursework/HIST1421/" title="Greek and Roman Civilization">HIST 1421</a> |
				<span class="hyperlink_unavailable" title="College Algebra">MATH 1201</span> |
				<span class="hyperlink_unavailable" title="Calculus">MATH 1211</span> |
				<span class="hyperlink_unavailable" title="Introduction to Statistics">MATH 1280</span> |
				<span class="hyperlink_unavailable" title="Discrete Mathematics">MATH 1302</span> |
				<span class="hyperlink_unavailable" title="Introduction to Philosophy">PHIL 1402</span> |
				<a href="/en/coursework/PHIL1404/" title="Ethics and Social Responsibility">PHIL 1404</a> |
				<a href="/en/coursework/POLS1503/" title="Globalization">POLS 1503</a> |
				<span class="hyperlink_unavailable" title="Introduction to Psychology">PSYC 1504</span> |
				<a href="/en/coursework/UNIV1001/" title="Online Education Strategies">UNIV 1001</a>
			</p>
			<hr/>
			<p>
				<a href="/en/coursework/CS1103/Unit1.java.xhtml" title="Unit1.java">Unit 1</a> |
				<a href="/en/coursework/CS1103/SimpleRandomSentences.java.xhtml" title="SimpleRandomSentences.java">Unit 2</a> |
				<a href="/en/coursework/CS1103/Tape.java.xhtml" title="Tape.java">Unit 3</a> |
				<a href="/en/coursework/CS1103/Debugging.xhtml" title="Debugging">Unit 4</a> |
				<a href="/en/coursework/CS1103/Unit5.java.xhtml" title="Unit5.java">Unit 5</a> |
				<a href="/en/coursework/CS1103/DrawTextPanel.java.xhtml" title="DrawTextPanel.java">Unit 6</a> |
				<a href="/en/coursework/CS1103/Unit7.java.xhtml" title="Unit7.java">Unit 7</a>
			</p>
			<hr/>
		</nav>
		<header>
			<h1>Learning Journal</h1>
			<p>CS 1103: Programming 2</p>
		</header>
<h2 id="Unit1">Unit 1</h2>
<p>
	I love open-ended, reflection-based learning journal assignments such as this one.
	Recording my activities in detail helps me review the material and better understand it.
	I also like being able to go back and read my learning journal entries later and see what my past self was thinking.
</p>
<p>
	The learning guide this week told us to read <a href="http://my.uopeople.edu/mod/page/view.php?id=67783">this page</a>, but it won&apos;t show us the contents.
	It says only students may view that page, however, I&apos;m logged in as a student and it won&apos;t show me the page.
	We&apos;re also supposed to read <a href="https://my.uopeople.edu/mod/resource/view.php?inpopup=true&amp;id=6286">this page</a>, but that&apos;s an error page.
</p>
<p>
	The <a href="http://math.hws.edu./eck/cs124/javanotes5/">textbook</a> for this course says it was written for Java 7.
	I&apos;ve dealt with some people that heavily push use of Java 8, but I much prefer sticking with Java 7 for now, so working with this textbook should be easy.
	I&apos;m on Debian 8, the latest stable version of my operating system, which includes OpenJDK 7 in its repositories.
	For that reason, OpenJDK 7 is the easiest, quickest, and safest version for me to install; I also already have it installed from last term.
</p>
<p>
	The reading list for this week is as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c3/s6.html#control.6.1">3.6.1 The Basic switch Statement</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c4/s5.html#subroutines.5.4">4.5.4 Javadoc</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c7/s2.html">Javanotes 5.1.2, Section 7.2 -- Array Processing</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c7/s3.html">Javanotes 5.1.2, Section 7.3 -- ArrayList</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c7/s4.html">Javanotes 5.1.2, Section 7.4 -- Searching and Sorting</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c7/s5.html">Javanotes 5.1.2, Section 7.5 -- Two-dimensional Arrays</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c8/s3.html">Javanotes 5.1.2, Section 8.3 -- Exceptions and try..catch</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c8/s6.html">Javanotes 5.1.2, Section 8.6 -- Analysis of Algorithms</a>
	</li>
</ul>
<p>
	As I tried to find the links to the reading material, I noticed that that last section didn&apos;t seem to exist.
	Chapter 8&apos;s last section was Section 8.5.
	I consulted the <abbr title="Portable Document Format">PDF</abbr> version provided by the university though, and sure enough, the section was there.
	So why wasn&apos;t it on the website?
	In the <abbr title="Portable Document Format">PDF</abbr>, I found a link to the online version, where I had my answer.
	The school gave us version 5.1.2 of the textbook, and the reading assignment&apos;s based on that.
	However, the link provided by the school isn&apos;t to version 5.1.2, but version 7.0.
	Inconsistent linking aside, why are we using an older version of the book?
	With a bit of digging, I found a reason for that too.
	It seems version 5.1.2 is the last version that&apos;s under a free license, <abbr title="Creative Commons Attribution-ShareAlike 2.5 Generic">CC BY-SA 2.5</abbr>.
	Versions of the book after this were released under a nonfree license and should be avoided if possible.
	It looks like this older book uses Java 5 though, so I may run into some differences in how things work on my end compared to how they work in the book.
</p>
<p>
	I find it interesting that strings, floats, and doubles can&apos;t be used in a <code>switch</code> statement.
	The lack of support for floats and doubles seems reasonable.
	After all, these data types are imprecise.
	There&apos;s a chance they won&apos;t catch what you think they will, and it&apos;s better to rely on something ... well, more reliable.
	As for strings, I wonder if that&apos;s because of the way Java treats strings.
	They&apos;re not a primitive data type, but instances of the <code>String</code> class.
	As such, it&apos;s harder to compare them.
	The <code>String.equals()</code> method works, but the <code>switch</code> construct isn&apos;t going to have a list of the methods each class uses to compare instances.
	My guess is that Java lacks support for objects of any class, not just strings, in <code>switch</code> statements.
</p>
<p>
	I was aware that Javadoc sees widespread use in the Java community.
	However, I was unaware that it was used to document the standard Java packages.
	I use a similar system for documenting my <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> code called phpDocumentor.
	Sadly, phpDocumentor is sort of a fringe thing, and there&apos;s no standard way to write <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> comments.
	I assumed Javadoc was similar, but with much more popularity.
	However, it&apos;s so deeply rooted in Java culture that even Java itself is using it.
	How awesome is that!?
	Additionally, the <code>javadoc</code> command isn&apos;t a third-party tool, but a part of the <abbr title="Java Development Kit">JDK</abbr>.
	That makes it almost, if not completely, a definitive standard.
	There&apos;s no real excuse <strong>*not*</strong> to use this commenting style, which is great.
	The textbook says though that Javadoc comments are ignored by the compiler just like regular comments, as if they&apos;re two separate things.
	This isn&apos;t the case though.
	Java comment blocks begin with <code>/*</code> and end with <code>*/</code>.
	It doesn&apos;t matter what character comes after <code>/*</code>, it&apos;s still a comment.
	Javadoc comments are, by Java syntax rules, just comments and nothing more.
	The second asterisk in the comment opening doesn&apos;t change what the block is, it just acts as a flag to Javadoc.
	Because Javadoc doesn&apos;t ignore comments, it sees and uses that flag.
	If I wanted to add my own flag to comments, I could, for example, open my comments with <code>/*+</code>; that would still be just a regular comment.
	It&apos;s useful to call Javadoc comments Javadoc comments instead of just comments, but only if we recognise that Javadoc comments are a <strong>*subset*</strong> of comments, not an entirely different syntactical element that just looks similar.
	It&apos;s interesting that Javadoc only gathers information about <code>public</code> elements by default; phpDocumentor doesn&apos;t do this, but logically should.
	If it&apos;s not declared <code>public</code>, other people won&apos;t be able to use those parts of the <abbr title="application programming interface">API</abbr>, so they don&apos;t need documentation on it.
	That documentation should still be available, both for internal use and for people tinkering with the code, but it probably shouldn&apos;t be visible by default.
</p>
<p>
	I hadn&apos;t thought about how to copy arrays in Java.
	The <code>System.arraycopy()</code> seems useful, though it&apos;s more complex than it probably needs to be; it takes five arguments for a job that will usually only require two.
	I suppose this provides flexibility though.
	The part on how for-each loops don&apos;t allow you to modify the array seemed pretty obvious.
	In essence, you&apos;ve got two variables pointing to the same value.
	The first variable is an element of an array, while the second is a regular variable used in the loop.
	The book says the two do not point to the same memory location.
	However, even if they did, assigning a new value to one of the variables shouldn&apos;t update the other variable.
	Actually .... hmm.
	Maybe that&apos;s not right.
	I&apos;m not used to dealing directly with memory locations.
	When a variable holds a reference to an object though, replacing that value with a reference to a new object doesn&apos;t change the value of any other variable that holds a reference to that same object.
	The logical and intuitive thing to me would be that changing the value of the variable in a loop would not affect the value in the original array.
	However ... if they shared a memory location, maybe the two would be completely entangled, and modifying one would modify them both.
	In any case, objects are not stored in variables in Java, only primitive-typed values are.
	Instead, references to objects are stored in variables.
	A copy of an object reference will point to the same object.
	That means that modifying an object withing a for each loop is possible, as long as you don&apos;t directly assign a new value to the loop&apos;s variable.
</p>
<p>
	The book mentions variable names such as <code>stringData[i].font</code>, calling them complex.
	If you know what you&apos;re doing, you can use names like this to make your code more concise.
	It works with methods and return values, too.
	Last term, I had an assignment in which one of the lines in my submission was simply <a href="https://y.st./en/coursework/CS1102/matchbox.xhtml"><code>new MatchBox(5, 10, 3).getVolume();</code></a>.
	We needed an object of class <code>MatchBox</code>, but we only needed it for one method call.
	After that, we were done with the object, so there was no point even storing it in a variable.
	Had we needed at least two method calls on the same object though, we&apos;d&apos;ve needed to store a reference to the object in a variable before using it.
	As long as you read it left to right (or use parenthesis correctly), you can chain quite a few things together.
	If it gets too long though, it&apos; gets difficult understanding exactly what&apos;s going on though, so it can be helpful to break it up into multiple statements and throw in some comments.
</p>
<p>
	The section on variable arity methods was informative.
	It&apos;s nice to be able to allow a variable number of elements be passed to the method.
	What I found most interesting though is that a method defined in this way can also instead take an array as an argument.
	I find this very strange, but it would indeed be a useful feature in some cases.
	Automatic boxing of primitive types in instances of wrapper classes is also an interesting concept.
	When these two concepts are combined, they can effectively cancel out Java&apos;s annoying overloading feature.
	Having multiple methods of the same name is never preferable behaviour in my opinion, with one exception: constructor methods.
	Aside from that, each method should be given a unique name; it makes the code that much easier to read.
	In practice though, I don&apos;t think using primitive type autoboxing and variable arity to funnel all calls to a particular method name to the single method they should be is good practice.
	It&apos;s needlessly complex, and probably even more confusing that just trying to dance around the annoying overloading feature.
	It&apos;s also interesting to note that when the generic <code>object</code> class is used as a variable type, values must be type cast to their proper, specific type before their class-specific methods can be used.
</p>
<p>
	This book explains the term &quot;dynamic arrays&quot; better than was explained last term.
	Last term, I kind of had to guess that dynamic arrays weren&apos;t really arrays at all, but array-like objects that can change in size.
	It seems my guess from last term was correct though.
	Parameterised types are also explained better.
	I&apos;m hoping we cover how to write classes that make use of this too, not just how to use built-in classes such as <code>java.util.ArrayList</code>.
</p>
<p>
	The book also explains that in some programming languages, an uncaught exception can crash the whole operating system.
	I guess I shouldn&apos;t be surprised though.
	It&apos;s not exactly an exception, but when I mistakenly write an infinite loop, I&apos;ve locked up my entire system before.
	Programs don&apos;t run in a vacuum.
	Poorly-written software can severely impact the function of other software running on the machine.
	Java&apos;s mandatory exception handling feature is interesting.
	For user-facing code, it&apos;s certainly a good thing.
	It requires that (certain types of) exceptions actually be handled, preventing crashes.
	That said, I sometimes write code for myself, code no user should ever need to run but me.
	When I do, I <strong>*want*</strong> my program to crash if it throws an exception.
	In such code, exceptions only get thrown and left uncaught in cases where I&apos;ve made a mistake and need to fix it.
	However, with mandatory exception handling, I&apos;d have to specifically catch the exception, then crash the program manually from within my <code>catch</code> block after printing a stack trace.
	It&apos;s doable, but seems like extra work just to code that which is already the default.
</p>
<p>
	I don&apos;t understand the technical terms on the analysis of algorithms page.
	I understand they&apos;re trying to measure completion time compared to problem size.
	From past experience, I understand that some algorithms have run times that grow linearly with problem size, while others have run times that grow exponentially.
	This seems like very basic knowledge to me, and I can usually understand even <strong>*why*</strong> a given algorithm would have a particular run time curve if I can see and understand the algorithm.
	I&apos;m worried this part might be too in-depth for me in my current state and that I&apos;m not ready to grasp that material, but I&apos;m hoping it&apos;s just poorly-explained.
</p>
<p>
	We used NetBeans for <a href="https://y.st./en/coursework/CS1102/" title="Programming 1">CS 1102</a>, but we&apos;re using Eclipse for this course.
	Eclipse is much easier to install on Debian 8.
	NetBeans is missing from the software repository, so dependency resolution has to be done by hand.
	With Eclipse though, running <code>sudo aptitude install eclipse</code> was all that needed to be done.
	It pulled in a lot of dependencies though.
	My package manager ended up installing seventy-eight new packages, which is kind of a lot.
	After installing it, I immediately rummaged through the configuration menu to make white space visible.
	That really should be the default in any <abbr title="integrated development environment">IDE</abbr>.
</p>
<p>
	The results of <a href="https://y.st./en/coursework/CS1103/Unit1.java.xhtml">this week&apos;s programming assignment</a> surprised me.
	I thought that the built-in <code>java.util.Arrays.sort()</code> would be faster than the other two algorithms, and I was right.
	Simply put, this method is likely implemented in a lower-level language, the one the Java compiler&apos;s written in.
	However, the difference between the selection sort and the insertion sort was very noticeable.
	Given the assignment instructions (we were to compare <strong>*one*</strong> of these algorithms with the built-in one), I thought the two would run about the same.
	However, I compared all three (because why not?), so I got a better picture.
</p>
<p>
	One of my classmates contacted me for help regarding Lab 1.
	That was fun!
	Their solution to the exercise used child classes of a base class.
	Instances of the child classes were passed into a method of the main class, but they felt their base class was useless.
	It was used only to group the child classes together to allow instances of all the child classes to be used as arguments.
	None of this base class&apos; methods were even used by the child classes, as the child classes overrode them all.
	I got to explain abstract methods, which allowed the unused base implementations to be removed.
	I also then explained interfaces, which were a better fit for that particular use case, as nothing but the method signatures needed to be inherited.
	They also asked about how to properly document member variables that are already obvious in their purpose even without comments.
	I didn&apos;t really have any sound advise on that part, but I did suggest a one-liner that simply and outright states what the variable represents and how its used.
</p>
<h3>Learning Journal exercise:</h3>
<p>
	The other labs were fun to complete, but it looks like we&apos;re only supposed to post our solutions to Lab 2 Part 1 here in the learning journal, not the solutions to both full labs.
	This was the solution I came up with:
</p>
<blockquote>
<pre>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit1;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 1 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 1 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. See the documentation of the main() method for information.
 * 
 * @author Alex Yst
 */
public class LearningJournalUnit1 {
/**
 * This method prompts the user for three values to plug into a quadratic
 * equation, then tells the user the larger of the two roots of that equation.
 * If something isn&apos;t right, an error message will instead be output. The
 * method loops endlessly as long as the user wants it to.
 * 
 * @param arguments Command line arguments are ignored.
 */
	public static void main(String[] arguments) {
		java.util.Scanner scanner = new java.util.Scanner(System.in);
		do {
			try {
				System.out.print(&quot;Please enter a numeric value for a: &quot;);
				double a = scanner.nextDouble();
				System.out.print(&quot;Please enter a numeric value for b: &quot;);
				double b = scanner.nextDouble();
				System.out.print(&quot;Please enter a numeric value for c: &quot;);
				double c = scanner.nextDouble();
				double root = root(a, b, c);
				System.out.print(&quot;The largest root of this quadradic equasion is: &quot;);
				System.out.println(root);
// root() throws these. They&apos;re the most likely exceptions to hit.
			} catch(IllegalArgumentException e) {
				System.out.print(&quot;An error has occured: &quot;);
				System.out.println(e.getMessage());
// java.util.Scanner.nextDouble() throws these if the user deliberately gives
// us bad data. We could just let the program crash, as the user&apos;s doing it to
// themself, but I don&apos;t want to. We can&apos;t output the exception&apos;s error message
// though, because there doesn&apos;t seem to be one.
			} catch(java.util.InputMismatchException e) {
				System.out.println(&quot;Your input appears malformed. It should be a number.&quot;);
			}
// This was the tricky part to figure out. For some reason, Java is capturing
// some unhelpful string here. I have some theories as to why it&apos;s doing that,
// but I can&apos;t find any consistency to the logic. However, navigating around
// the issue is easy enough. By calling this method here, we clear out whatever
// buffer was being read from. We only need to call the method, not necessarily
// capture its useless output. Now, when we call the method next time, the
// output won&apos;t be useless; it&apos;ll actually be what we&apos;re after.
			scanner.nextLine();
			System.out.print(&quot;Type \&quot;continue\&quot; to enter another quadratic or any other value to exit: &quot;);
		} while(scanner.nextLine().equals(&quot;continue&quot;));
		System.out.print(&quot;Exiting.&quot;);
		scanner.close();
	}
/**
 * Returns the larger of the two roots of the quadratic equation
 * A*x*x + B*x + C = 0, provided it has any roots. If A == 0 or
 * if the discriminant, B*B - 4*A*C, is negative, then an exception
 * of type IllegalArgumentException is thrown.
 * 
 * This method was copied from
 * &lt;http://math.hws.edu./eck/cs124/javanotes5/c8/s3.html&gt;. This method, along
 * with the rest of the book that contains it, was released under the CC BY-SA
 * 2.5 license. According to the Creative Commons compatibility list, CC BY-SA
 * 2.5 works may be upgraded to be covered by version 4.0 of the same license,
 * and works under CC BY-SA are compatible with the GNU GPLv3. It is therefore
 * my understanding that I may incorporate this method into this GPLv3 class.
 * If you feel this is incorrect, please let me know and I&apos;ll do my best to
 * remedy the situation. For more information, the Creative Commons
 * compatibility list is available here:
 * &lt;https://creativecommons.org/share-your-work/licensing-considerations/compatible-licenses/&gt;.
 * 
 * @author David J. Eck
 */
	static public double root( double A, double B, double C ) throws IllegalArgumentException {
		if (A == 0) {
			throw new IllegalArgumentException(&quot;A can&apos;t be zero.&quot;);
		} else {
			double disc = B*B - 4*A*C;
			if (disc &lt; 0)
				throw new IllegalArgumentException(&quot;Discriminant &lt; zero.&quot;);
			return  (-B + Math.sqrt(disc)) / (2*A);
		}
	}
}</pre>
</blockquote>
<h2 id="Unit2">Unit 2</h2>
<p>
	The reading list for the week was as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c9/s1.html">Javanotes 5.1.2, Section 9.1 -- Recursion</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c9/s2.html">Javanotes 5.1.2, Section 9.2 -- Linked Data Structures</a>
	</li>
</ul>
<p>
	One of this week&apos;s big topics was recursion.
	I don&apos;t often get a chance to use recursion, as it&apos;s kind of a specialised tool when used correctly, but it&apos;s fun to work with.
	I didn&apos;t notice right away, but the programming assignment of the week is slightly recursive.
	Language grammar (both in natural languages and constructed) tend to be either be recursive if they&apos;re good at expressing much, and the assignment this week shows part of that off in the second method we were to write.
	A couple of the other methods have a chance of calling each other too, resulting in indirect recursion.
</p>
<p>
	I&apos;ve heard of quick sort, but I&apos;d never heard what that actually was.
	It&apos;s an interesting algorithm, and I&apos;m surprised it&apos;s actually fast in most cases.
	Intuitively, it seems like a slow way to sort, to me.
</p>
<p>
	The reading material makes a good point as far as defining something in terms of itself.
	Intuitively, you can&apos;t do that.
	You&apos;ll end up with a circular (and thus meaningless) definition.
	However, defining something <strong>*partially*</strong> in terms of itself is a powerful tool, and is exactly what recursion is.
	It also mentions generalisation via the adding of extra parameters that are used recursively to pass information known about the problem so far.
	In some languages, such as <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> and Lua, these parameters can be made optional, so the main use case doesn&apos;t require the extra input.
	This doesn&apos;t work in Java though, where all parameters are mandatory.
	You could use method overloading, but it&apos;s an extremely obnoxious feature, and I&apos;d avoid using method overloading in all cases aside from constructor methods.
</p>
<p>
	I found it interesting that the book said it&apos;s difficult to think recursion works.
	It&apos;s probably true, but I&apos;ve been using recursion so long I don&apos;t even remember.
	I use it extremely sparingly; so far, all but one example of recursion in the book is a problem I&apos;d choose to solve instead with loops.
	However, when I do use recursion, I use it precisely and powerfully.
	It&apos;s easy these days for me to see why and how it does its job.
	It&apos;s also worth noting that in the employee/supervisor example, infinite recursion is possible if the employee objects reference one another in a loop, or en employee is mistakenly marked as their own supervisor.
	In an actual hierarchy, this wouldn&apos;t happen, but it&apos;s an interesting case to think about in the context of understanding whether an algorithm can ever complete.
	This line of thought also applies to the objects used as nodes in a list; their references too could be circular.
</p>
<p>
	The learning journal code for the week really made me think.
	I&apos;ve seen an elegant solution in the past, and I was going to apply what made it so elegant to my own code; that is, until I realised I couldn&apos;t.
	The language won&apos;t let me.
	As the assignment instructions say, the factorial and Fibonacci functions take up a lot of memory needlessly.
	There&apos;s a way to fix that though.
	All you need is a key/value store that keeps track of all the values you&apos;ve already computed.
	Put the base values in the starting state of the key/value store (as opposed to treating them as a special case in the logic), then add values to the store as you find them.
	Never again will running into a known case require recomputing.
	First, the recursive method checks for the value, by key, in the store.
	If it&apos;s found, that&apos;s the base case, and that value is returned.
	Otherwise, it&apos;s computed by calling itself recursively using the equation.
	Java doesn&apos;t offer arrays with arbitrary keys though.
	Objects also can&apos;t have arbitrary properties.
	Java is a complete language, so there <strong>*has*</strong> to be a way to implement this, but I don&apos;t know what it is.
	When research didn&apos;t turn up anything, I had to write up a solution using the obvious method.
	That method is both boring and inefficient though.
	The only other problem I ran into was that Java doesn&apos;t seem to have the <code>or</code> key word of other languages.
	Switching it out for the <code>||</code> operator was an easy solution though.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit2;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 2 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 2 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. See the documentation of the main() method for information.
 * 
 * @author Alex Yst
 */
public class LearningJournalUnit2 {
/**
 * This method computes the factorial of any non-negative integer. It&apos;s not
 * very efficient in its implementation and can eat system resources for large
 * values of n.
 * 
 * @param n A non-negative integer
 * @return The factorial of n
 */
	public static int factorial(int n) {
		if(n &lt; 0) {
			throw new IllegalArgumentException(&quot;The argument passed to factoral() can&apos;t be negative.&quot;);
		} else if(n == 0) {
			return 1;
		} else {
			return n * factorial(n-1);
		}
	}
/**
 * This method computes the Fibonacci of any non-negative integer. It&apos;s not
 * very efficient in its implementation and can eat system resources for large
 * values of n.
 * 
 * @param n A non-negative integer
 * @return The Fibonacci of n
 */
	public static int fibonacci(int n) {
		if(n &lt; 0) {
			throw new IllegalArgumentException(&quot;The argument passed to fibonacci() can&apos;t be negative.&quot;);
		} else if(n == 0 || n == 1) {
			return 1;
		} else {
			return fibonacci(n-1) + fibonacci(n-2);
		}
	}
/**
 * This program computes a few factorials and Fibonaccis as a proof of concept.
 * The method in which this program works is incredibly inefficient. An
 * improved version would use some sort of lookup table of answers we&apos;ve
 * already computed. But how does one implement that in Java?
 * 
 * @param arguments Command line arguments are ignored.
 */
	public static void main(String[] arguments) {
		System.out.println(factorial(2));
		System.out.println(fibonacci(3));
		System.out.println(factorial(5));
		System.out.println(fibonacci(7));
		System.out.println(factorial(11));
		System.out.println(fibonacci(13));
	}
}</code></pre>
</blockquote>
<h2 id="Unit3">Unit 3</h2>
<p>
	The reading list for this week is as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c9/s3.html">Javanotes 5.1.2, Section 9.3 -- Stacks, Queues, and ADTs</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c9/s4.html">Javanotes 5.1.2, Section 9.4 -- Binary Trees</a>
	</li>
</ul>
<p>
	When I saw the discussion assignment this week, I assumed it was referring to class interfaces.
	However, the learning guide said that it referred to things such as queues and stacks.
	While interfaces have obvious modularity-promoting qualities, I&apos;m quite confused as to how queues and stacks have anything to do with modularity.
	The reading material, both in the textbook and in the learning guide, say that when a program depends on an abstract data type, it can use any (they actually said &quot;either&quot;, but there&apos;s no actual reason as to why there would be only two) implementation interchangeably.
	Again, class interfaces allow for this, but abstract data types do not.
	To make a program run using a different implementation of an abstract data type, the program&apos;s logic <strong>*must*</strong> me modified.
	The methods of retrieving data from and adding data to a queue or stack isn&apos;t the same when using a linked list as when using an array, nor are either set of methods the same as when using an <code>ArrayList</code>!
	Linked lists can be implemented using different attributes and classes even, so the <abbr title="application programming interface">API</abbr> for a linked list isn&apos;t even always going to be the same.
	Changing implementations will almost always involve a logic rewrite.
</p>
<p>
	The examples of this in the book though use a class to implement the abstract data type.
	No interface is used, so I wouldn&apos;t call different implementations fully interchangeable, but as long as you kept the signatures of the public methods the same, you could in theory remove an old implementation and replace it with a new one.
	Still, I don&apos;t think this speaks much of the value of abstract data types in interchangability; more, it&apos;s just the re-implementation of a class.
	Any class can be re-implemented like that, even if you don&apos;t have an abstract data type for the class to represent.
</p>
<p>
	I already knew what queues and stacks are, but I&apos;d never heard of a postfix expression.
	The notation on those is strange, and for more-complex expressions, a bit of a pain to read.
	It&apos;s stated that this notation form is good because it removes the need for parentheses and the order of operations.
	It&apos;s possible to use a more-readable notation style that doesn&apos;t have the order of operations though, and I&apos;m not convinced that the option to use parentheses to group part of an expression is ever a bad thing.
</p>
<p>
	The textbook mentioned a way to keep binary trees balanced automatically.
	This seems to me like a difficult task to handle efficiently.
	I&apos;d&apos;ve loved to see examples of good ways to implement that feature.
</p>
<p>
	The test for the week had some hilarious options.
	One question asked:
</p>
<blockquote>
	<p>
		How do you study a text book?
	</p>
</blockquote>
<p>
	One of the available choices was:
</p>
<blockquote>
	<p>
		(1) Cram all the pages in one horrible session, and (2) forget everything the next night.
	</p>
</blockquote>
<p>
	Another question asked:
</p>
<blockquote>
	<p>
		How can you drink an entire keg of root beer?
	</p>
</blockquote>
<p>
	Two of the available responses were:
</p>
<blockquote>
	<p>
		(1) take one enormous gulp, and (2) wish you hadn&apos;t.
	</p>
</blockquote>
<blockquote>
	<p>
		(1) drink one keg, and (2) drink another keg.
	</p>
</blockquote>
<p>
	The results of the programming exercise this week were interesting.
	I expected the average leaf depth to fluctuate a bit between program runs, but I expected it to stay about at the perfect balance level, sometimes being above and sometimes being below.
	In retrospect, it&apos;d be impossible for the tree&apos;s average leaf depth to fall below the level of balance perfection, so it actually only stays above that line.
	Most of the time, the depth seems to stay at thirteen, though I have seen it as high as fourteen and as low as eleven.
	The maximum depth seems to have a wider range of fluctuation.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit3;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 3 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 2 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. If included as a module in another program, this class acts as a
 * base for creating simple tree node objects. If instead run as a program
 * itself, it&apos;ll randomly generate a tree of 1023 nodes, then tell the average
 * and maximum leaf depth, then exit.
 * 
 * @author Alex Yst
 */
public class LearningJournalUnit3 {
/**
 * The value held by this node
 */
	private double value;
/**
 * A subtree of all values less than this node&apos;s value
 */
	private LearningJournalUnit3 less;
/**
 * A subtree of all values more than this node&apos;s value
 */
	private LearningJournalUnit3 more;
/**
 * Constructor method
 * 
 * @param d The value of the new node
 */
	public LearningJournalUnit3(double d) {
		value = d;
	}
/**
 * Inserts a new value in an existing tree. THE TREE MUST EXIST, AND THEREFORE
 * ALREADY HAVE AT LEAST ONE VALUE. Use the constructor method instead if
 * adding the first value to a new tree.
 * 
 * @param d The new value to insert
 */
	public void treeInsert(double d) {
		if(d &lt; value) {
			if(less == null) {
				less = new LearningJournalUnit3(d);
			} else {
				less.treeInsert(d);
			}
		} else {
			if(more == null) {
				more = new LearningJournalUnit3(d);
			} else {
				more.treeInsert(d);
			}
		}
	}
/**
 * Counts the leaves in the tree
 * 
 * @return The number of leaves
 */
	public int countLeaves() {
		if(less == null &amp;&amp; more == null) {
			return 1;
		} else {
			int leaves = 0;
			if(less != null) {
				leaves += less.countLeaves();
			}
			if(more != null) {
				leaves += more.countLeaves();
			}
			return leaves;
		}
	}
/**
 * Finds the sum of all leaf depths. The argument passed to this method should
 * always be zero. PASSING ANY OTHER VALUE TO THIS METHOD WILL CAUSE IT TO
 * RETURN AN INCORRECT VALUE.
 * 
 * @param depth The current working depth
 * @return The sum of all leaf depths
 */
	public int totalLeafDepths(int depth) {
		depth += 1;
		int total = 0;
		if(less != null) {
			total += less.totalLeafDepths(depth);
		}
		if(more != null) {
			total += more.totalLeafDepths(depth);
		}
		if(total == 0) {
			total = depth;
		}
		return total;
	}
/**
 * Finds the maximum leaf depth. The argument passed to this method should
 * always be zero. PASSING ANY OTHER VALUE TO THIS METHOD WILL CAUSE IT TO
 * RETURN AN INCORRECT VALUE.
 * 
 * @param depth The current working depth
 * @return The maximum leaf depth
 */
	public int maximumDepth(int depth) {
		depth += 1;
		if(less == null &amp;&amp; more == null) {
			return depth;
		} else {
			int depthLess = 0;
			int depthMore = 0;
			if(less != null) {
				depthLess = less.maximumDepth(depth);
			}
			if(more != null) {
				depthMore = more.maximumDepth(depth);
			}
			if(depthLess &gt; depthMore) {
				return depthLess;
			} else {
				return depthMore;
			}
		}
	}
/**
 * This method outputs the debug information when this class is run as a
 * program instead of as a module.
 * 
 * @param arguments Command line arguments are ignored.
 */
	public static void main(String[] arguments) {
// With this class&apos; setup, there are no empty trees. We need to generate the
// first node to have any tree to work with at all. This setup allows us to not
// have to set up a static method. Without a static method, trees can exist
// independently of one another. In other words, we can have an arbitrary
// number of trees.
		LearningJournalUnit3 tree = new LearningJournalUnit3(Math.random());
// This will add 1022 nodes, but since we started with one node, it&apos;ll add up
// to the required 1023 nodes.
		for(int i=0;i&lt;1022;i++) {
			tree.treeInsert(Math.random());
		}
		System.out.print(&quot;Average depth: &quot;);
		System.out.println(tree.totalLeafDepths(0) / tree.countLeaves());
		System.out.print(&quot;Maximum depth: &quot;);
		System.out.println(tree.maximumDepth(0));
	}
}</code></pre>
</blockquote>
<h2 id="Unit4">Unit 4</h2>
<p>
	Unfortunately, my laptop died on me at the beginning of the week.
	I lost the first day of the week due to needing to catch up with last week.
	The next day, my laptop died on me before I could get any coursework done, but I didn&apos;t have time to go get a replacement because I had a shift at work.
	The next day, I replaced the machine with one from the recycling centre before work and downloaded the operating system.
	And on the next day, I finished the hardware swapping (the new machine didn&apos;t have a working Wi-Fi card), installing the new operating system, backing up my data from the old machine (the old hard drive was still intact), transferring it to the new machine, and installing my usual software bundle (including software needed for school, such as KeePassX and Eclipse).
	That left me with three days left to cram a week&apos;s worth of studying into, and two of those days were work days for me.
	I managed to get one of those shifts covered, but not the other.
	Needless to say, this wasn&apos;t a week of heavy reflection on the material, and was instead a week of frantic cramming.
	My new machine is slow, but at least it runs my familiar Debian environment, so I didn&apos;t have to struggle to learn a new system while simultaneously struggling to catch up in my studies.
</p>
<p>
	The reading assignment for the week was as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c9/s5.html">Javanotes 5.1.2, Section 9.5 -- A Simple Recursive Descent Parser</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c10/s1.html">Javanotes 5.1.2, Section 10.1 -- Generic Programming</a>
	</li>
</ul>
<p>
	One of this week&apos;s topics is syntax specification in Backus-Naur Form.
	I&apos;m actually fairly familiar with that notation, due to the <abbr title="Request for Comments">RFC</abbr>s often employing the similar Augmented Backus-Naur Form.
	The book notes that Backus-Naur Form cannot be used to express certain syntax rules, such as that a variable must be declared before being used.
	I find it outright bizarre that this would be considered a syntax rule at all though.
	Syntax deals with the structure of the program, but attempting to use a variable before it&apos;s been declared is more of a logical error.
	The structure of the statements is valid, you&apos;re just attempting to perform an operation on a value that does not yet exist.
	As far as <strong>*actual syntax rules*</strong>, Backus-Naur Form is pretty strong.
	As the textbook states, finding the fact that a variable is referenced before being defined requires parsing the program into some other form, for example, a parse tree.
	An error that cannot be found during parsing, but instead only <strong>*after*</strong> parsing, is not a syntax error.
</p>
<p>
	The other main topic for the week was generic programming.
	Whenever possible, programs should be written in a generic manner.
	This allows for greater flexibility, both for the user during normal use and for the developer when updating the code.
	New features are easier to implement when you don&apos;t have to write your way around a bunch of use-specific code; you don&apos;t need to write in yet more exceptions (not exceptions as in throwable objects, but exceptions as in cases in which data is handled differently).
	Generic programming also aids in code reuse, as you don&apos;t have to invent a bunch of similar wheels.
	Instead, you can invent a single wheel that accomplishes the genetic task at hand.
</p>
<p>
	The specific type of generic programming discussed this week dealt with programming classes in such a way that they could offer type-specific features without having to use a different class definition for each and every type used.
	Classes can be built and used that accept only objects of a specific type into their structures, but that type is chosen at run time.
	We still haven&apos;t covered how to program these classes, but using the ones already existing in Java is a trivial task.
</p>
<p>
	Iterators and interfaces were also covered, but that was all review for me.
	I&apos;ve worked a lot with interfaces on my own in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>; their main advantage being that you can require a class to implement a given method, but the details of how that method functions internally can be tailored to the structure of the actual objects of that class.
	The use of iterators is about the same, and in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>, they&apos;re implemented with either the <code>\Iterator</code> or <code>\IteratorAggregate</code> interface.
	I haven&apos;t done any work with the later, but the former has allowed me to build several, very-different sorts of iterable object classes.
</p>
<p>
	The assignment this week was a doozy.
	Debugging by hand is bad enough, but debugging using obtuse debugging tools is even worse.
	I managed to get the debugging done though.
	Eclipse warned me about some of the bugs before I even started the debugger though, so I needed to clean those up before even running it.
	Three of the bugs caused compiler errors, while the fourth caused a method other than the sorting methods to fail to execute properly.
</p>
<p>
	Grading the assignments from last week, I got the distinct impression that one of the students didn&apos;t test their code after writing it.
	The constructor method creates a new cell, immediately deletes it, then tries to set the properties of the deleted object.
	It results in a thrown exception any time a new <code>Tape</code> object is instantiated.
	The <code>moveLeft()</code> and <code>moveRight()</code> methods also don&apos;t actually move the pointer.
	Additionally, the code tries to call these methods from the <code>Tape</code> class on objects of the <code>Cell</code> class.
	This code is so full of errors that it can&apos;t function without some major clean-up.
</p>
<p>
	The learning journal assignment this week was a challenge.
	I started out trying to parse the user input one way, then gave up and patched together a finite state machine.
	It&apos;s probably not the best example of one, as I&apos;ve never built one before, but I learned about them a while back.
	I figured one would be an adequate tool for the job, and it&apos;d allow the statefull processing of the string that I needed.
	I started out trying to use an integer to keep track of what state the machine was in, but I quickly came to a fork in which I needed to jump forward some steps.
	(If an ending square bracket followed a beginning square bracket, the steps of processing the contents of the set would be skipped.
	This is a valid case, as the set could be empty.)
	I didn&apos;t want to risk putting the wrong integer in place, so I was about to set up named constants for each integer in use.
	That was when it hit me.
	I could just use Java&apos;s <code>enum</code>s!
	Not only would I have named constants to work with, but the mode flag would also be constrained to having only valid flag values!
	Perfect.
	I&apos;ve never really had a use for <code>enum</code>s until this point, so it was nice to see a valid use case for them.
	Java did the heavy lifting as far as the set operations went.
	For that reason, I don&apos;t even think this assignment was about set operations.
	I think it was more about string-parsing.
	It&apos;s too bad this was a learning journal assignment and not a peer-graded assignment; I&apos;d love to see what solutions other students came up with.
	Looking back, maybe I was supposed to build a parse tree instead of interpreting the string as I parsed it?
	That would&apos;ve tied in better with this week&apos;s material, but I wasn&apos;t sure how to accomplish it, given that a set can hold any number of numbers and a Java object can only hold a finite and predetermined number of properties.
	I guess I could&apos;ve done a very-obtuse tree structure, but that seems inefficient, not to mention that it seems like overkill.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit4;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 4 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 4 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. See the documentation of the main() method for information.
 * 
 * @author Alex Yst
 */
public class LearningJournalUnit4 {
/**
 * A finite state machine has ... well, a finite number of states in which it
 * can be in. This enum gives a referencable name to each of these states.
 */
	public enum MODE {
		FIRST_SET_EXPECTED,        // &apos;[&apos; required
		FIRST_SET_FOUND,           // Digit or &apos;]&apos; required
		FIRST_SET_NUMBER,          // Digit, &apos;,&apos;, or &apos;]&apos; required
		FIRST_SET_NUMBER_EXPECTED, // Digit required
		SECOND_SET_EXPECTED,       // &apos;[&apos; required
		SECOND_SET_FOUND,          // Digit or &apos;]&apos; required
		SECOND_SET_NUMBER,         // Digit, &apos;,&apos;, or &apos;]&apos; required
		SECOND_SET_NUMBER_EXPECTED,// Digit required
		OPERATOR_EXPECTED,         // &apos;[&apos; not allowed
		END_EXPECTED,              // No character allowed
	};

/**
 * This method prompts the user for set operations. A finite state machine is used
 * to parse the operation, then the operation is carried out and the result is
 * output. This continues looping until the user enters an empty string. Empty
 * sets are explicitly allowed, but negative numbers are not. Spaces are
 * ignored. Long numbers, such as &quot;1000000000&quot; can be written in the form
 * &quot;1 000 000 000&quot; for clarity for example, and they&apos;ll still be interpreted
 * correctly.
 * 
 * @param arguments Command line arguments are ignored.
 */
	public static void main(String[] arguments) {
		java.util.Scanner scanner = new java.util.Scanner(System.in);
		System.out.println(&quot;Enter two sets separated by an operator to perform the operation on those sets.&quot;);
		System.out.println(&quot;Enter an empty line to exit the program.&quot;);
		String input = scanner.nextLine();
		while(!input.equals(&quot;&quot;)) {
			try {
				java.util.TreeSet&lt;Integer&gt; set0 = new java.util.TreeSet&lt;Integer&gt;();
				java.util.TreeSet&lt;Integer&gt; set1 = new java.util.TreeSet&lt;Integer&gt;();
				MODE mode = MODE.FIRST_SET_EXPECTED;
// Setting this explicitly fixes a warning in Eclipse. The value will be set to
// something else later on though. The only way to skip over the code that sets
// this value is enter a string that will throw an exception before the
// operator is found. In those cases though, we don&apos;t need the operator anyway.
				char operator = &apos;!&apos;;
				boolean done = false;
				String number = &quot;&quot;;
				for(int i=0;i&lt;input.length();i++) {
					char c = input.charAt(i);
					if(c == &apos; &apos;) {// intentionally empty
					} else {
						switch(mode) {
							case FIRST_SET_EXPECTED:
								if(c == &apos;[&apos;) {
									mode = MODE.FIRST_SET_FOUND;
								} else {
									throw new Exception(&quot;Opening square bracket not found.&quot;);
								}
							break;
							case FIRST_SET_FOUND:
								if(Character.isDigit(c)) {
									number += c;
									mode = MODE.FIRST_SET_NUMBER;
								} else if(c == &apos;]&apos;) {
									mode = MODE.OPERATOR_EXPECTED;
								} else {
									throw new Exception(&quot;First number of first set not found.&quot;);
								}
							break;
							case FIRST_SET_NUMBER:
								if(Character.isDigit(c)) {
									number += c;
								} else if(c == &apos;,&apos;) {
									set0.add(Integer.parseInt(number));
									number = &quot;&quot;;
									mode = MODE.FIRST_SET_NUMBER_EXPECTED;
								} else if(c == &apos;]&apos;) {
									set0.add(Integer.parseInt(number));
									number = &quot;&quot;;
									mode = MODE.OPERATOR_EXPECTED;
								} else {
									throw new Exception(&quot;Digit, comma, or closing square bracket expected; &apos;&quot;+c+&quot;&apos; found at possition &quot;+i+&quot;.&quot;);
								}
							break;
							case FIRST_SET_NUMBER_EXPECTED:
								if(Character.isDigit(c)) {
									number += c;
									mode = MODE.FIRST_SET_NUMBER;
								} else {
									throw new Exception(&quot;Digit expected; &apos;&quot;+c+&quot;&apos; found at possition &quot;+i+&quot;.&quot;);
								}
							break;
							case SECOND_SET_EXPECTED:
								if(c == &apos;[&apos;) {
									mode = MODE.SECOND_SET_FOUND;
								} else {
									throw new Exception(&quot;Opening square bracket not found.&quot;);
								}
							break;
							case SECOND_SET_FOUND:
								if(Character.isDigit(c)) {
									number += c;
									mode = MODE.SECOND_SET_NUMBER;
								} else if(c == &apos;]&apos;) {
									mode = MODE.END_EXPECTED;
									done = true;
								} else {
									throw new Exception(&quot;First number of second set not found.&quot;);
								}
							break;
							case SECOND_SET_NUMBER:
								if(Character.isDigit(c)) {
									number += c;
								} else if(c == &apos;,&apos;) {
									set1.add(Integer.parseInt(number));
									number = &quot;&quot;;
									mode = MODE.SECOND_SET_NUMBER_EXPECTED;
								} else if(c == &apos;]&apos;) {
									set1.add(Integer.parseInt(number));
									number = &quot;&quot;;
									mode = MODE.END_EXPECTED;
									done = true;
								} else {
									throw new Exception(&quot;Digit, comma, or closing square bracket expected; &apos;&quot;+c+&quot;&apos; found at possition &quot;+i+&quot;.&quot;);
								}
							break;
							case SECOND_SET_NUMBER_EXPECTED:
								if(Character.isDigit(c)) {
									number += c;
									mode = MODE.SECOND_SET_NUMBER;
								} else {
									throw new Exception(&quot;Digit expected; &apos;&quot;+c+&quot;&apos; found at possition &quot;+i+&quot;.&quot;);
								}
							break;
							case OPERATOR_EXPECTED:
// If we don&apos;t explicitly check for an opening square bracket here, we still
// get the correct results. The only issue is that some of the error messages
// are ... confusing. I found myself writing up a long comment on how the
// confusing error message for this situation was intended behaviour and not a
// and not a bug, but I realised that the mere fact that I had to explain
// myself meant that it kind of *was* a bug.
// 
// I&apos;m explaining myself here, but it&apos;s not to try to convince anyone that
// confusing behaviour is in some way correct; it&apos;s just to show why a single,
// seemingly-random character is checked for: it makes the program more
// user-friendly.
								if(c == &apos;[&apos;) {
									throw new Exception(&quot;No operator found.&quot;);
								} else {
									operator = c;
									mode = MODE.SECOND_SET_EXPECTED;
								}
							break;
							case END_EXPECTED:
								throw new Exception(&quot;End expected; &apos;&quot;+c+&quot;&apos; found at possition &quot;+i+&quot;.&quot;);
						}
					}
				}
				if(!done) {
					throw new Exception(&quot;End of expression not found.&quot;);
				}
				switch(operator) {
					case &apos;+&apos;:
						set0.addAll(set1);
					break;
					case &apos;*&apos;:
						set0.retainAll(set1);
					break;
					case &apos;-&apos;:
						set0.removeAll(set1);
					break;
					default:
						throw new Exception(&quot;Invalid operator: &apos;&quot;+operator+&quot;&apos;.&quot;);
				}
				System.out.println(set0);
			} catch(Exception e) {
				System.out.print(&quot;Malformed input; ERROR: &quot;);
				System.out.println(e.getMessage());
			}
			input = scanner.nextLine();
		}
		scanner.close();
	}
}</code></pre>
</blockquote>
<h2 id="Unit5">Unit 5</h2>
<p>
	The reading assignment for the week was as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c10/s2.html">Javanotes 5.1.2, Section 10.2 -- Lists and Sets</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c10/s3.html">Javanotes 5.1.2, Section 10.3 -- Maps</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c10/s4.html">Javanotes 5.1.2, Section 10.4 -- Programming with the Collection Framework</a>
	</li>
</ul>
<p>
	When I read what the learning journal exercise would be for the week, I was a bit less than enthusiastic at first.
	We were to implement our own hash table.
	That part sounded fun, but there was a catch: we were to use a linked list to store the values.
	What!?
	Wouldn&apos;t a tree implementation be so much more efficient?
	With a tree, we could quickly and effectively decide both where to place a new item and where to look for an existing item.
	However, as I read the assigned sections of the textbook, I figured out why we were to use a linked list.
	In a linked list, it&apos;s easy to find the next and previous items.
	With a tree, that&apos;d be so much more of a challenge.
	I still say a tree is a better back end for a hash table in most cases, but when we need to move forward and backward through the list, a tree just isn&apos;t going to cut it.
	Maps don&apos;t allow iteration directly, but through the use of views, it&apos;s plenty possible.
</p>
<p>
	After further reading though, I finally understood.
	Hash maps are implemented as an array of linked lists, which also explained the reference to array size in the assignment instructions, which I didn&apos;t get at first either.
	I figured the hashed keys needed to be used similar to values in how they determined where a node fell in a sorted data type.
	A tree with two values per node, with the hashed key being the value that determined node placement seems like an effective storage technique to me, but that&apos;s not what a hash map is.
	The book also mentioned that items in a hash table occasionally get reordered, but I forgot about that by the time the implementation of hash maps was explained.
	Thankfully, the book next talked about <strong>*why*</strong>.
	It&apos;s too bad the learning journal says not to implement the array expansions.
	That means that a finite number of linked lists will be used, with no changes as the data changes.
	It&apos;d be easy to keep a count of how many values are in the hash map; a simple integer object property could be incremented and decremented as values are added and removed.
	Instead, to allow at least some flexibility while still following the directions, I had the array size chosen at instantiation time.
	If a lot of data is expected, a larger integer can be passed to the constructor to construct a larger array, and vice versa for a smaller array.
</p>
<p>
	I was confused as to why the absolute value of the hash code needed to be found.
	After all, we were just going to perform modulo division on it.
	Modulo division always results in a positive number, right?
	Does Java not do things that way?
	I pulled up Eclipse to test, and sure enough, I was getting a negative number.
	That couldn&apos;t be right though.
	I pulled up a command line and tried in my native language, <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>.
	Surprisingly, I got the same negative result.
	What in the world!?
	My understanding of modulo division is that it wraps numbers, forcing them into the range of zero through whatever number you modulo by, with zero being inclusive and the other number being exclusive.
	By this definition, nothing outside this range should ever be returned.
	What&apos;s the point of modulo division if it doesn&apos;t coerce numbers into a desired range?
	As far as I knew, that&apos;s it&apos;s primary and <strong>*only*</strong> purpose.
	Clearly, my definition was wrong, so I looked it up.
	The typical statement on modulo division is that it&apos;s about remainders, but that definition isn&apos;t actually accurate for one simple reason: there is <strong>*never*</strong> any remainder.
	Five divided by two isn&apos;t two with a remainder of one; it&apos;s just two point five.
	Furthermore, the entire concept of a remainder seems to break down when either the dividend or the divisor isn&apos;t an integer.
	<a href="https://en.wikipedia.org/wiki/Modulo_operation">Wikipedia</a> had this to say:
</p>
<blockquote cite="https://en.wikipedia.org/wiki/Modulo_operation">
	<p>
		The range of numbers for an integer modulo of n is 0 to n − 1.
	</p>
</blockquote>
<p>
	In other words, my assessment from before was correct after all.
	However, Wikipedia also had this to say (&quot;a&quot; being the dividend and &quot;n&quot; being the divisor):
</p>
<blockquote cite="https://en.wikipedia.org/wiki/Modulo_operation">
	<p>
		When either a or n is negative, the naive definition breaks down and programming languages differ in how these values are defined.
	</p>
</blockquote>
<p>
	The definition breaks down ...
	It sounds like modulo division using negative numbers isn&apos;t exactly defined, but at the same time, isn&apos;t exactly disallowed.
	This results in different languages implementing it differently, with the two I tried using the same implementation.
	Weird.
	Why are such operations undefined?
	It seems like a major hole in the definition, to me.
</p>
<p>
	I&apos;m often a stickler for details, even ones that don&apos;t matter.
	The book offered <code>Math.abs(obj.hashCode()) % N</code> as a way to compute a hash code within the desired range, but that didn&apos;t seem quite right.
	It would certainly return an integer in the range we need it to, but with the flaw that negative numbers are treated strangely.
	Assuming <code>Y</code> is positive, if <code>X % Y</code> returns zero, then <code>(X-1) % Y</code>will return <code>(Y - 1)</code> if <code>X</code> is positive, but will return one if <code>X</code> is negative.
	That&apos;s just one example of the strange properties introduced, too.
	Another is the fact that at zero, both one above and one below result in the same hash position.
	As the assignment didn&apos;t specify an algorithm to use, I decided to roll out something more consistent.
	It performs the modulo division, checks to see if it&apos;s negative, and if so, add the divisor.
	This simple solution provides consistency, while additionally implementing modulo division as I&apos;ve always understood it to function.
</p>
<p>
	The book mentions that tree sets of the built-in <code>TreeSet</code> class are balanced.
	As with last time auto-balanced trees were mentioned, I&apos;m left wondering how this is accomplished.
	Keeping a tree automatically balanced seems like a good feature, but it also seems computationally expensive.
	There&apos;s got to be a good way to do it.
</p>
<p>
	I was disappointed in the submission from last week from one of my fellow students.
	Their own output shows that they failed to find at least two bugs.
	When your output continues to show bugs, why would you not keep debugging?
	It also didn&apos;t provide any explanation as to how the bugs were found, which I feel like was the entire point of the assignment.
	The goal wasn&apos;t to find the fixes as much as it was to explain how we found the bugs.
	Fixing the broken code was merely a way to show that the bugs we found were the only bugs present.
	By removing all bugs we found, we could produce valid output to prove it.
	Another student also failed to find one of the bugs, so their output must&apos;ve been invalid, but they didn&apos;t include any output.
	Like the other student, they included no explanation as to how they found the bugs either.
	The assignment was a bit of a pain, but it&apos;s like these two students didn&apos;t even try, which saddens me.
</p>
<p>
	I started my hash map implementation by attempting to implement the <code>java.util.Map</code> interface.
	That plan quickly fell apart.
	The assignment specifically states that we are <strong>*not*</strong> to build a generalised mapping class, but one that works only on strings.
	Changing the method signatures to take only strings resulted in the interface not being properly implemented.
	At first, I was going to give up and just not implement the interface, but then I decided to see if parametrised types would work in the <code>implements</code> clause.
	They do!
	That fixed up the method signatures while still allowing objects on my class to be considered maps as long as the code using them was trying to map strings to strings.
	Next, I tried to have my node class extend the <code>String</code> class.
	The <code>String</code> class has everything we need to represent strings, it just isn&apos;t on its own chainable into linked lists.
	I just needed to add a single property to it to link to the next string.
	No dice though.
	The <code>String</code> class is <code>final</code>, so I had to build a full wrapper class for the linked list nodes after all.
</p>
<p>
	The next issue I ran into was a lack of information on certain methods, such as <code>compute()</code>, <code>computeIfAbsent()</code>, and <code>computeIfPresent()</code>.
	What was I supposed to have these methods <strong>*do*</strong>?
	What are the <code>BiFunction</code>- and <code>Function</code>-type arguments used for?
	After at least an hour of trying to figure out what to do with these methods, I reread the assignment directions hoping for clues.
	The instructions are actually pretty specific about what methods need to be implemented, actually, and they make no mention of the <code>java.util.Map</code> interface at all.
	The secret to completing the assignment is simply to not use the intuitive interface for it.
	Not using the interface makes my assignment submission feel incomplete in my eyes, but it brings the assignment back into the realm of feasibility.
	Quite frankly, we haven&apos;t covered these methods, so I had no chance of figuring out how to implement them.
	Maybe we&apos;ll go more in-depth about Java maps in a later unit, or even a later course.
	Being able to throw out the more-complicated methods, I deleted those three method signatures.
	... strangely, Eclipse didn&apos;t complain about unimplemented methods though.
	What&apos;s going on?
	Those method signatures only existed in my class because <strong>*Eclipse*</strong> automatically put them there to satisfy the interface&apos;s requirements, yet they don&apos;t seem to be required at all.
	So why did Eclipse add them even!?
	I&apos;d wasted a lot of time, just because Eclipse decided to behave strangely.
	It&apos;s no wonder I couldn&apos;t find any information on these method signatures of the <code>java.util.Map</code> interface; they&apos;re not even a <strong>*part*</strong> of the <code>java.util.Map</code> interface!
	I deleted every method, one by one, checking each to see which Eclipse complained about not having.
	I found several other unneeded methods.
	I wouldn&apos;t mind trying my hand at implementing them, if there was any excuse whatsoever <strong>*to*</strong> implement them, but there really isn&apos;t.
	Even implementing the interface is a bit of a stretch, and I probably should&apos;ve skipped that.
</p>
<p>
	I never could get Eclipse to accept anything I tried to define <code>putAll()</code> as.
	It didn&apos;t like when I parametrised the variable I tried to store the return value of <code>arg0.entrySet()</code> in, but also wouldn&apos;t allow me to parametrise it.
	I was at a loss as to what to do, and I ran out of time.
	I ended up having to abandon this method, and in the process, abandon the implementation of the <code>java.util.Map</code> interface.
	I also ended up having to skip the <code>entrySet()</code> method.
	I <strong>*guess*</strong> I still met the minimum requirements of the assignment, but it still feels like a failure to me.
	At some point when I have more time, I should go back and attempt to complete this class.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit5;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 5 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 5 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. See the documentation of the main() method for information.
 * 
 * @author Alex Yst
 */
public class LearningJournalUnit5 {
/**
 * This is just a simple test program to make sure the methods of the HashMap
 * class output reasonable data and take reasonable action. This is by no means
 * an exhaustive test.
 * 
 * @param args
 */
	public static void main(String[] args) {
		HashMap map = new HashMap(8);
		map.put(&quot;key0&quot;, &quot;value0&quot;);
		map.put(&quot;key1&quot;, &quot;value1&quot;);
		map.put(&quot;key2&quot;, &quot;value2&quot;);
		map.put(&quot;key3&quot;, &quot;value3&quot;);
		map.put(&quot;key4&quot;, &quot;value4&quot;);
		map.put(&quot;key5&quot;, &quot;value5&quot;);
		map.put(&quot;key6&quot;, &quot;value6&quot;);
		map.put(&quot;key7&quot;, &quot;value7&quot;);
		map.put(&quot;key8&quot;, &quot;value8&quot;);
		map.put(&quot;key9&quot;, &quot;value9&quot;);

		map.put(&quot;key2&quot;, &quot;These &quot;);
		map.put(&quot;key3&quot;, &quot;are &quot;);
		map.put(&quot;key5&quot;, &quot;prime &quot;);
		map.put(&quot;key7&quot;, &quot;numbers.&quot;);

		System.out.print(map.get(&quot;key2&quot;));
		System.out.print(map.get(&quot;key3&quot;));
		System.out.print(map.get(&quot;key5&quot;));
		System.out.println(map.get(&quot;key7&quot;));

		System.out.print(&quot;Map contained key five before: &quot;);
		System.out.println(map.containsKey(&quot;key5&quot;));
		map.remove(&quot;key5&quot;);
		System.out.print(&quot;Map contained key five after: &quot;);
		System.out.println(map.containsKey(&quot;key5&quot;));
		System.out.print(&quot;Map size (should be nine): &quot;);
		System.out.println(map.size());

		System.out.print(&quot;Map contains value zero: &quot;);
		System.out.println(map.containsValue(&quot;value0&quot;));
		System.out.print(&quot;Map contains value five: &quot;);
		System.out.println(map.containsValue(&quot;value5&quot;));

		System.out.print(&quot;Map is empty before clearing all items: &quot;);
		System.out.println(map.isEmpty());
		map.clear();
		System.out.print(&quot;Map size after clearing all items: &quot;);
		System.out.println(map.size());
		System.out.print(&quot;Map is empty after clearing all items: &quot;);
		System.out.println(map.isEmpty());
	}
}</code></pre>
</blockquote>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit5;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 5 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 5 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. This class acts as a base for linked nodes for the hash map.
 * 
 * @author Alex Yst
 */
public class Node {
/**
 * The key for the key/value store
 */
	public String key;
/**
 * The value for the key/value store
 */
	public String value;
/**
 * The next node in the linked list, if any
 */
	public Node next;
/**
 * The previous node in the linked list, if any
 */
	public Node prev;
/**
 * Constructor method. This method just sets up the basic values of the node.
 * New nodes are inserted at the head, not the tail, so freshly-added values
 * are located first. Inserting at the tail, so older values can be found
 * first, would be equally-valid, but more difficult to implement.
 * 
 * @param k The key
 * @param v The value
 * @param n The next node in the chain, if any
 */
	public Node(String k, String v, Node n) {
		key = k;
		value = v;
		next = n;
		if(next != null) {
			next.prev = this;
		}
	}
}</code></pre>
</blockquote>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit5;

/**
 * Alex Yst&apos;s CS 1103 (Programming 2) Unit 5 Learning Journal
 * 
 * This class was programmed to fill the requirements on the Unit 5 learning
 * journal assignment in University of the People&apos;s CS 1103 (Programming 2)
 * course. Objects of this class act as a hash map. Unfortunately, I ran out of
 * time, and couldn&apos;t implement two of the methods required for implementing
 * the standard Java map interface, but that was never one of the requirements
 * for the project.
 * 
 * @author Alex Yst
 */
public class HashMap {
/**
 * The main hash array
 */
	private Node[] map;
/**
 * Constructor method. The larger the number passed to this method, the more
 * memory the object will take up. The smaller the number, the less efficient
 * the map will be.
 * 
 * @param size The size of the new object&apos;s hash array
 */
	public HashMap(int size) {
		map = new Node[size];
	}
/**
 * Used internally. Returns the index of the array holding the linked list that
 * a particular key belongs to.
 * 
 * @param key An object to use as a key
 * @return An array index
 */
	private int getHashCode(Object key) {
		int code = key.hashCode() % map.length;
		if(code &lt; 0) {
			code += map.length;
		}
		return code;
	}
/**
 * Clears all objects in the map without altering the map&apos;s array size.
 */
	public void clear() {
		map = new Node[map.length];
	}
/**
 * Checks to see if a given key is in the map.
 * 
 * @param arg0 A key to check
 * @return True if the key is in the map, false otherwise
 */
	public boolean containsKey(Object arg0) {
		Node node = map[getHashCode(arg0)];
		while(node != null) {
			if(node.key.equals(arg0)) {
				return true;
			} else {
				node = node.next;
			}
		}
		return false;
	}
/**
 * Checks to see if a given value is in the map
 * 
 * @param arg0 A value
 * @return True if the value is in the map, false otherwise
 */
	public boolean containsValue(Object arg0) {
		for(int i=0;i&lt;map.length;i++) {
			Node node = map[i];
			while(node != null) {
				if(node.value.equals(arg0)) {
					return true;
				} else {
					node = node.next;
				}
			}
		}
		return false;
	}
/**
 * Returns the value associated with a key, or null if the key/value pair
 * doesn&apos;t exist.
 * 
 * @param arg0 The key
 * @return The value
 */
	public String get(Object arg0) {
		Node node = map[getHashCode(arg0)];
		while(node != null) {
			if(node.key.equals(arg0)) {
				return node.value;
			} else {
				node = node.next;
			}
		}
		return null;
	}
/**
 * Checks to see if the map is empty
 * 
 * @return True if the map is empty, false oftherwise
 */
	public boolean isEmpty() {
		for(int i=0;i&lt;map.length;i++) {
			if(map[i] != null) {
				return false;
			}
		}
		return true;
	}
/**
 * This method adds a key if it doesn&apos;t exist, and associates a value with that
 * key, regardless of if the key existed before.
 * 
 * @param arg0 The key
 * @param arg1 The value
 * @return The previous value, if any was associated with the key
 */
	public String put(String arg0, String arg1) {
		int code = getHashCode(arg0);
		Node node = map[code];
		while(node != null) {
			if(node.key.equals(arg0)) {
				String previousValue = node.value;
				node.value = arg1;
				return previousValue;
			} else {
				node = node.next;
			}
		}
		Node previousNode = map[code];
		map[code] = new Node(arg0, arg1, previousNode);
		return null;
	}
/**
 * Removes a key and its value from the map.
 * 
 * @param arg0 The key
 * @return The former value, if any
 */
	public String remove(Object arg0) {
		int code = getHashCode(arg0);
		Node node = map[code];
		while(node != null) {
			if(node.key.equals(arg0)) {
				if(node.prev == null) {
					map[code] = node.next;
				} else {
					node.prev.next = node.next;
				}
				if(node.next != null) {
					node.next.prev = node.prev;
				}
				return node.value;
			} else {
				node = node.next;
			}
		}
		return null;
	}
/**
 * Returns the number of key/value pairs in the map.
 * 
 * @return The number of key/value pairs
 */
	public int size() {
		int size = 0;
		for(int i=0;i&lt;map.length;i++) {
			Node node = map[i];
			while(node != null) {
				node = node.next;
				size++;
			}
		}
		return size;
	}
/**
 * This method returns a linked list of values from the map.
 * 
 * @return A linked list of values from the map
 */
	public java.util.Collection&lt;String&gt; values() {
		java.util.LinkedList&lt;String&gt; c = new java.util.LinkedList&lt;String&gt;();
		for(int i=0;i&lt;map.length;i++) {
			Node node = map[i];
			while(node != null) {
				c.add(node.value);
			}
		}
		return c;
	}
/**
 * This method returns a hash set of keys from the map.
 * 
 * @return A hash set of values from the map
 */
	public java.util.Set&lt;String&gt; keySet() {
		java.util.HashSet&lt;String&gt; s = new java.util.HashSet&lt;String&gt;();
		for(int i=0;i&lt;map.length;i++) {
			Node node = map[i];
			while(node != null) {
				s.add(node.key);
			}
		}
		return s;
	}
}</code></pre>
</blockquote>
<h2 id="Unit6">Unit 6</h2>
<p>
	The learning guide mentions that we should know the syntax for file paths in both UNIX and Windows.
	I already know both, but it&apos;s worth noting that knowing the Windows file path syntax isn&apos;t very useful.
	Windows accepts paths specifies in the UNIX syntax, so by using the UNIX syntax, you make your program cross-platform compatible.
	At times, it can help to be able to <strong>*read*</strong> a Windows file path, because they do come up every once in a while if you&apos;re working on that platform.
	However, there is zero reason why most people should ever <strong>*write*</strong> a path in the Windows-specific syntax.
</p>
<p>
	It&apos;s mentioned by the learning guide that when you read a <abbr title="Joint Photographic Experts Group">JPEG</abbr>, you only get an approximation of what&apos;s saved.
	You also only save an approximation of what was in memory before you saved it.
	This has some interesting consequences, and if you&apos;re working with any sort of art you need to edit later, you shouldn&apos;t be saving as a <abbr title="Joint Photographic Experts Group">JPEG</abbr>.
	If you copy a <abbr title="Joint Photographic Experts Group">JPEG</abbr> file, the result is an exact copy, as with any other file.
	However, if you open up a <abbr title="Joint Photographic Experts Group">JPEG</abbr> file in an editor, don&apos;t make a single change, then save it again, it&apos;ll degrade the quality of the file.
	Saving again has no effect, as it&apos;s still the same image data in memory, but that&apos;s not the case if you close the file and open it again.
	Every time you close, open, and save the file, more quality will be lost.
	It&apos;s arguable (but also debatable) that <abbr title="Joint Photographic Experts Group">JPEG</abbr> is a decent format for photographic data, but for <strong>*any*</strong> other type of image, including graphic art, use of the <abbr title="Joint Photographic Experts Group">JPEG</abbr> format should be avoided.
</p>
<p>
	The reading material for the week was as follows:
</p>
<ul>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c11/s2.html">Javanotes 5.1.2, Section 11.2 -- Files</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c11/s4.html">Javanotes 5.1.2, Section 11.4 -- Networking</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s1.html">Javanotes 5.1.2, Section 12.1 -- Images and Resources</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s2.html">Javanotes 5.1.2, Section 12.2 -- Fancier Graphics</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s3.html">Javanotes 5.1.2, Section 12.3 -- Actions and Buttons</a>
	</li>
</ul>
<p>
	The first example of opening a file found in this week&apos;s reading material provided comments, saying to declare the <code>FileReader</code> object&apos;s variable <strong>*before*</strong> the <code>try</code>/<code>catch</code> statement.
	That way, the variable will exist outside the context of the <code>try</code> block, and can be used elsewhere in the program.
	Why in the <strong>*world*</strong> would you do that!?
	If the file isn&apos;t found, the variable will contain a null pointer!
	You expressly <strong>*don&apos;t*</strong> want to use the variable outside the <code>try</code> block.
	You should, before ending the <code>try</code> block, use the <code>FileReader</code> to do whatever you need it to do, then call the <code>close()</code> method.
	That actually brings me to another point, which is that you should call the <code>close()</code> method when you&apos;re done, and you don&apos;t want to try calling that on a null pointer.
	I <strong>*guess*</strong> you could wrap each method call in an <code>if</code> block, but why not use the already-existing <code>try</code> block?
	Why make things more complex than they need to be?
	You&apos;re probably going to have to go a different direction in your program anyway if the file&apos;s not found, so it&apos;s not like you can continue on simply by keeping the null pointer around.
</p>
<p>
	The version of the <code>java.awt.Image.drawImage()</code> method that allows the use of only part of an image to be used seems <strong>*incredibly*</strong> useful to me.
	It seems like just the thing for use with tile sets.
	There&apos;s no need to separate each tile in a computer game into its own file, especially when there could be thousands of tiles.
	With this method, using each tile from a tile set should be a snap.
	It&apos;s interesting that only <abbr title="Portable Network Graphic">PNG</abbr>, <abbr title="Graphics Interchange Format">GIF</abbr>, and <abbr title="Joint Photographic Experts Group">JPEG</abbr> images are supported in standard Java.
	It seems outright bizarre that uncompressed formats such as bitmaps aren&apos;t supported as well.
	Really though, anything a bitmap can do, a <abbr title="Portable Network Graphic">PNG</abbr> can do with a smaller file size, so bitmaps shouldn&apos;t be used as program resources anyway.
</p>
<p>
	I&apos;d heard of antialiasing before, especially in regards to fonts.
	I never actually looked up what it was though.
	It&apos;s interesting to finally know what antialiasing (and aliasing) are.
	Without knowing what it was, I&apos;ve had to perform anti-antialiasing sometimes when working with images.
	When I work in the <abbr title="GNU Image Manipulation Program">GIMP</abbr>, I occasionally use the circle tool, which performs automatic antialiasing.
	However, for my use case, this is almost never the desired behaviour.
	I end up needing to crate a new layer, fill it with a fully-opaque colour, use the circle select tool, bucket fill the circle with the opposite colour as the background, then posterise the layer.
	Posterising allows you to cast the layer into a smaller colour space by rounding all the colours.
	In my case, I use a posterisation level of two, which means that for each the red, green, and blue channels, there are only two options: fully red, green, or blue; or not red, green, or blue at all.
	This results in eight possible colour options: <code>#000</code>, <code>#00f</code>, <code>#0f0</code>, <code>#0ff</code>, <code>#f00</code>, <code>#f0f</code>, <code>#ff0</code>, and <code>#fff</code>.
	I can then delete the background colour, providing transparency to the non-circle part of the layer, and I can recolour the circle to whatever colour I need it to be.
	Now that I know the terminology though, I can do this the easy and correct way.
	It seems the <abbr title="GNU Image Manipulation Program">GIMP</abbr> allows antialiasing to be turned off in the circle-select tool, providing the aliased look I usually go for.
	On a large scale, antialiasing is probably preferred, but I usually work on such a small scale that all it does is cause unwanted blur.
</p>
<p>
	The constructor method for <code>javax.swing.KeyStroke</code> is interesting.
	It seems strange that it parses keystrokes out of a string.
	From a computer-minded standpoint, this seems inefficient.
	Maybe an array or a <code>Map</code> would be better?
	From an <abbr title="application programming interface">API</abbr>-usability standpoint though, I can see why this was done.
	A simple string of space-delimited key codes does seem easier to read, write, and maintain.
	It&apos;s also strange that keyboard accelerators cannot be applied directly to actions, but only menu items.
	This also means that buttons can&apos;t have keyboard accelerators associated with them.
	If you want a keyboard shortcut, it <strong>*must*</strong> actually be a shortcut, and not the main way to perform an action.
</p>
<p>
	When I opened up the project files for this week, they all seemed to be full of errors.
	The error in <code>DirectoryList.java</code> was fixable; the file was just missing a package declaration.
	I was baffled by the errors in the other files though.
	Eclipse complained about access restrictions on certain classes and was asking to search for Java packages to download.
	When I gave it the go-ahead, it acted like I hadn&apos;t and did nothing.
	Eventually, I found the issue.
	Eclipse has been setting up new projects to use Java 1.4.
	I&apos;m not sure why that&apos;s the default, but throwing out the project and beginning a new one that uses Java 1.7 cleared up all the problems aside form the easy-to-fix missing package declaration.
	<code>DrawTextPanel.java</code> had a few warnings about missing methods, but no outright errors.
	Because we were supposed to work with <code>DrawTextPanel.java</code>, these warnings would no doubt need to be cleaned up by the end of the week.
	A warning in <code>DirectoryList.java</code> was about an unclosed <code>Scanner</code> resource, and that was easy enough to fix, so I fixed that one as well.
</p>
<p>
	I went back to the instructions, and noticed I was supposed to have imported four files.
	I&apos;d imported five.
	The <code>DirectoryList.java</code> file that&apos;d been missing its package declaration was missing it not because of a bug, but because it wasn&apos;t part of the project.
	It was instead for use in the learning journal assignment for the week.
	After completing the first task for the programming project, the allowing of multiple strings, I found the menu commands and control + z kind of behaved stupidly, when it came to undoing changes.
	Exactly one change could be undone, no more than that.
	It was fine behaviour for when only one string were allowed, but didn&apos;t fit the current state of the program.
	I tried removing the line responsible for that feature, and found if I tried to undo more changes than had been made, the program would throw an exception and crash.
	Conditionally executing the disabling feature made the program run smoothly though.
</p>
<p>
	For the next step, saving the data in a plain text format, the instructions recommended putting each value on its own line.
	That seems insane to me though.
	If a known number of values are to be saved, that approach could work.
	However, we&apos;re working with an unknown number of coloured strings that a user has placed on the canvas.
	There could be many or few values.
	An important thing to note too is that the values are <strong>*grouped*</strong>.
	If the values weren&apos;t grouped, it could still be feasible to give each value its own line in the file, even if the number of values wasn&apos;t known.
	In our case though, putting each value on its own line would interfere with extensibility.
	New version of the program would be unable to load files created from old versions of the program.
	No, what we need is to put each <strong>*group*</strong> of values on one line, and separate the values themselves with something other than a line feed.
	The text-input field of the program seems to disallow the entering of tab characters, so tab characters should never appear in any of the user-entered strings.
	That makes them a perfect fit for the problem.
	I set up the first line to hold the values of the background, and each line after that to hold the values of a given string.
	With the sets separated, it&apos;s easy to see where values that were added later are missing and provide some sort of default for them.
	Additionally, older versions of the program should be able to read files written by newer versions, as long as they account for the possibility of extra values and simply ignore those values.
	Files won&apos;t be handled perfectly, but it&apos;s better than outright rejecting files written to disk by other versions of the software.
	My initial file format saved just the bare minimum asked for by the assignment.
	I figured once I got that working, I could add onto it as needed.
	However, strangely enough, the instructions don&apos;t require the text&apos;s <strong>*coordinates*</strong> to be saved.
	Before I got a change to even <strong>*think*</strong> about how to load the file, I noticed the file format wouldn&apos;t work.
	Coordinates were an absolute requirement.
</p>
<p>
	My chosen feature to add was the option to import a background instead of using a solid background colour.
	Instead of starting right away on that though, I added keyboard shortcuts for the menu items that didn&apos;t have them.
	It seemed inconsistent to have a few menu items have the shortcuts while the rest didn&apos;t.
	Once I got to implementing my actual feature, I found it was more difficult of a problem to solve than I thought it&apos;d be, but the code for it was simpler than I was expecting.
	However, once I got it set up, I noticed that if a non-image file were loaded, the file would simply be ignored.
	Instead, I was expecting an error message.
	Something in my code wasn&apos;t right.
	It seems Java doesn&apos;t throw any exceptions when a non-image is used to create a <code>Image</code> object.
	I found a way around that, and put in some specific, type-checking code, and that did the trick.
	I&apos;d love to have tried my hand at adding even more features, but I ran out of time again.
	This week was almost as bad as last week, as far as outside-of-class drama issues.
	Lastly, I added a couple constants that the <code>JPanel</code> class seemed to want in child classes.
	These constants were version integers and the code had never been released until just now, so I set them to the only sensible initial version number: zero.
</p>
<p>
	I keep thinking things will get better, but it was another long week.
	I was glad to see that the learning journal exercise for the week was an easy one.
	We were to create a class for recursively listing files in a directory.
	I actually already had to build something very similar in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> so I could compile my website (<abbr title="PHP: Hypertext Preprocessor">PHP</abbr> is a scripted language, but it can actually be used to compile static pages if you write your code in such a way to do so), so I&apos;m already very familiar with what&apos;s required.
	The main difference with the class in the assignment and the function I wrote before was that this class listed the files (<strong>*including*</strong> directories) to standard output, while my previous function returned the list of non-directory files to be processed by other code.
	I wasn&apos;t sure if directories were supposed to be listed or just the non-directory files they contained, so I wrote my program to list both, but mark each for easy identification.
	I also modified the program to output full file paths.
	This made it easy to see were the files are nested, but more than that, it makes it easy to see exactly where on the file system the file is.
	When I use <code>ls --recursive</code> on the command line, one of my annoyances is that it <strong>*doesn&apos;t*</strong> show the full file paths like this.
	It makes it impossible to use <code>grep</code> to locate the location of a file I can&apos;t find; I can see if the file exists, but not where to find it.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package st.y.CS1103.LearningJournalUnit6;

import java.io.File;
import java.util.Scanner;

/**
 * This program lists the files in a directory specified by
 * the user.  The user is asked to type in a directory name.
 * If the name entered by the user is not a directory, a
 * message is printed and the program ends.
 */
public class DirectoryList {


	public static void main(String[] args) {

		String directoryName;  // Directory name entered by the user.
		File directory;        // File object referring to the directory.
		Scanner scanner;       // For reading a line of input from the user.

		scanner = new Scanner(System.in);  // scanner reads from standard input.

		System.out.print(&quot;Enter a directory name: &quot;);
		directoryName = scanner.nextLine().trim();
		directory = new File(directoryName);

		if (directory.isDirectory() == false) {
			if (directory.exists() == false)
				System.out.println(&quot;There is no such directory!&quot;);
			else
				System.out.println(&quot;That file is not a directory.&quot;);
		} else {
			System.out.println(&quot;Files in directory \&quot;&quot; + directory + &quot;\&quot;:&quot;);
			recurse(directory);
		}
		scanner.close();
	} // end main()
/**
 * Directories are prefixed with &quot;[dir ]&quot;, while non-directory files are
 * prefixed with &quot;[file]&quot;.
 * 
 * @param directory A File object representing a file system directory
 */
	public static void recurse(File directory) {
		System.out.println(&quot;[dir ]\t&quot; + directory.getPath());
		String[] files = directory.list();
		for(String filename : files) {
			File file = new File(directory, filename);
			if(file.isDirectory()) {
				recurse(file);
			} else {
				System.out.println(&quot;[file]\t&quot; + file.getPath());
			}
		}
	}
} // end class DirectoryList</code></pre>
</blockquote>
<h2 id="Unit7">Unit 7</h2>
<p>
	The reading assignment for the week was as follows:
</p>
<ul>
	<li>
		<a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model–view–controller - Wikipedia</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s3.html">Javanotes 5.1.2, Section 12.3 -- Actions and Buttons</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s4.html">Javanotes 5.1.2, Section 12.4 -- Complex Components and MVC</a>
	</li>
	<li>
		<a href="http://math.hws.edu./eck/cs124/javanotes5/c12/s5.html">Javanotes 5.1.2, Section 12.5 -- Finishing Touches</a>
	</li>
	<li>
		<a href="http://www.oracle.com/technetwork/java/mvc-140477.html">Design Patterns: Model-View-Controller</a>
	</li>
</ul>
<p>
	I&apos;m surprised the first part of the reading assignment is on Wikipedia.
	While I personally think Wikipedia is a good source of information, especially on well-understood concepts (basically, everything except the obscurest of topics), universities and other educational institutions often seem to disagree.
</p>
<p>
	It&apos;s interesting to see what all Java classifies as buttons.
	Some things in particular, such as menu items, seem like quite a stretch of the definition of &quot;button&quot; to me, but at the same time, I can&apos;t outright say they&apos;re definitely <strong>*not*</strong> buttons.
	You do click them, after all, and when you do, there&apos;s some sort of effect.
	One important aspect of actions that the textbook mentioned is that they allow you to enable and disable <strong>*all*</strong> associated buttons at once.
	It doesn&apos;t matter how many buttons you add for the same action (maybe one in the main menu, one on the tool bar, one in the settings dialogue, ...), you can enable and disable them all at once using the action&apos;s methods.
	This was review though, due to an overlap between this week&apos;s reading assignment and last week&apos;s.
</p>
<p>
	The syntax for anonymous subclasses seems odd, but it shouldn&apos;t be too hard to get used to.
	That said, I&apos;ve never really been one to use anonymous classes.
	However, I&apos;m also not used to working in a language in which all code is contained in a class.
	When I work in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>, I make sure all my classes and most of my functions are generic.
	To date, I&apos;ve only written one function that I couldn&apos;t generalise enough to warrant making into a full, named function, so I made it an anonymous function.
	In Java though ...Even the main program has to be a class method.
	It&apos;s quite possible I&apos;ll use anonymous classes in Java more freely than I do in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>.
</p>
<p>
	The textbook finally, near its end, covered the package-naming conventions of Java.
	I&apos;ve actually known about these conventions though for a while, which is why I&apos;ve prefixed all my package names for this course with <code>st.y.CS1103</code>.
	I control the name <code>y.st.</code> in <abbr title="Domain Name System">DNS</abbr>, which is where my surname, Yst (pronounced the same as in the words &quot;cr<strong>yst</strong>al&quot; and &quot;catal<strong>yst</strong>&quot;), comes from.
	I&apos;ve never liked my gender-based birth name, so when I legally changed my given name to the gender-neutral name Alex (short for Alexander (masculine), Alexandra (feminine), and Alexis (neutral)), I also changed my surname to show my geeky side.
	I&apos;ve used this naming convention for longer than I&apos;ve known about it being the de-facto standard in Java too, just because I&apos;m a <abbr title="Domain Name System">DNS</abbr> geek that cares about proper namespacing.
	I use this same convention in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr>, which doesn&apos;t really have a standard way of deciding on what namespace to use.
	I didn&apos;t use this convention last term like I normally do due to the fact that we were using NetBeans, which isn&apos;t really set up to allow for proper package naming, but Eclipse, which we&apos;ve been using this tern, is.
</p>
<p>
	I find it very strange that a Java properties file can&apos;t contain Unicode characters.
	Most languages can process Unicode characters just fine, though they don&apos;t always behave as expected.
	For example, each byte in a multibyte string might get counted when you measure the length of a string, but there shouldn&apos;t be any difficulties in reading such strings from a file.
</p>
<p>
	The concepts of window parents and modeless windows are interesting.
	It makes sense that when a window&apos;s parent closes, the window would close as well.
	The window likely doesn&apos;t have any meaningful context without its parent.
	Modeless windows seem unintuitive at first glance, but they definitely have a purpose.
	I find sometimes when I open up a settings window in an application, I need to select and copy text from the main window.
	However, because the settings dialogue is modal, I can&apos;t do that.
	I annoyingly have to close the settings dialogue, copy the text, open a new settings dialogue, and navigate back to the setting I was trying to modify.
	This is particularly cumbersome when I need to copy multiple strings into the settings.
	If these settings dialogues were modeless, it&apos;d be much easier to get done what I need to; and this is only one example I&apos;ve run into when using software.
</p>
<p>
	Grading was interesting this week.
	The first student disappointed me though.
	They uploaded the wrong file of the multi-file program.
	Instead of sending the only file we were supposed to modify, they sent one of the unmodified ones.
	The next student added a redo feature to their code.
	Nice!
	I wish I&apos;d thought of that.
	The final student added several options for displaying the added text in different ways.
	In my original plan, I wanted to add those features in addition to my background image feature, but there simply wasn&apos;t time.
	It&apos;s been a hard month, outside of school.
</p>
<p>
	The assignment this week involved building part of a Web server.
	It was a struggle because of my continued lack of time, but other than that, it was incredibly awesome to see how it works.
	It makes me want to try building a more-complete Web server in <abbr title="PHP: Hypertext Preprocessor">PHP</abbr> (my native language).
	There <strong>*is*</strong> a small catch though.
	In my eyes, a Web server that doesn&apos;t handle <abbr title="Transport Layer Security">TLS</abbr> isn&apos;t worth putting time into (unless it&apos;s an assignment or something), so I&apos;ll need to figure out how to implement <abbr title="Transport Layer Security">TLS</abbr> support nearly right away.
	No website should be served without privacy-aiding encryption.
	I haven&apos;t looked into it yet, so I could be dead wrong, but I get the impression that <abbr title="Transport Layer Security">TLS</abbr> is difficult to work with.
	I guess I&apos;ll see though when I start trying to make this happen.
	After I get a few current projects squared away, I&apos;d like to work on this in my free time (assuming I ever get any free time).
</p>
<p>
	When I started work on the learning journal exercise, I thought I was missing a file.
	The <code>TestStopWatchRunner</code> class was coded to use another class, <code>StopWatchRunner</code>, which I couldn&apos;t find code for.
	Simply changing <code>StopWatchRunner</code> to <code>StopWatchLabel</code> got the code to run (and have the expected behaviour) though, so it must&apos;ve just been a mistake in the code, not a missing class file.
	Once I had the initial code working, I started working on modifying it to meet the assignment&apos;s instructions.
	The task seemed daunting and overwhelming at first, but it was actually a very easy task and quickly accomplished.
	The only real snag even was that once I got it working, the display would flash &quot;Timing....&quot; before displaying that no seconds had elapsed.
	That was easily fixable by modifying that string in the source code though.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2006 David J. Eck
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 * 
 * Notes:
 * 
 * Copied from &lt;http://math.hws.edu./eck/cs124/javanotes5/c12/s4.html&gt;, which
 * was released under the Creative Commons Attribution-ShareAlike 2.5 License.
 * The mousePressed() method was modified in this version and the timer and
 * action attributes added, both by Alex Yst. This code is released under the
 * GNU GPLv3+. This is possible because the CC BY-SA 2.5 license allows
 * upgrading to any later version of CC BY-SA and CC BY-SA 4.0 allows upgrading
 * to the GNU GPL.
 * 
 * @author David J. Eck
 * @author Alex Yst
 */
import java.awt.event.*;
import javax.swing.*;


/**
 * A custom component that acts as a simple stop-watch.  When the user clicks
 * on it, this component starts timing.  When the user clicks again,
 * it displays the time between the two clicks.  Clicking a third time
 * starts another timer, etc.  While it is timing, the label just displays
 * the number of complete seconds passed without fractional seconds counted.
 */
public class StopWatchLabel extends JLabel implements MouseListener {

	private long startTime;   // Start time of timer.
	                          //   (Time is measured in milliseconds.)

	private boolean running;  // True when the timer is running.
/**
 * This action will be performed every 200 milliseconds while the timer is
 * running.
 */
	private ActionListener action = new ActionListener() {
		public void actionPerformed(ActionEvent event) {
			long seconds = (event.getWhen() - startTime) / 1000;
			setText(&quot;Time: &quot; + seconds + &quot; sec.&quot;);
		}
	};
/**
 * This timer is started and stopped with the rest of the stopwatch.
 */
	private Timer timer = new Timer(200, action);

/**
 * Constructor sets initial text on the label to
 * &quot;Click to start timer.&quot; and sets up a mouse listener
 * so the label can respond to clicks.
 */
	public StopWatchLabel() {
		super(&quot;  Click to start timer.  &quot;, JLabel.CENTER);
		addMouseListener(this);
	}


/**
 * Tells whether the timer is currently running.
 */
	public boolean isRunning() {
		return running;
	}


/**
 * React when the user presses the mouse by starting
 * or stopping the timer and changing the text that
 * is shown on the label.
 */
	public void mousePressed(MouseEvent evt) {
		if (running == false) {
// Record the time and start the timer.
			timer.start();
			running = true;
			startTime = evt.getWhen();  // Time when mouse was clicked.
			setText(&quot;Time: 0 sec.&quot;);
		} else {
// Stop the timer.  Compute the elapsed time since the
// timer was started and display it.
			timer.stop();
			running = false;
			long endTime = evt.getWhen();
			double seconds = (endTime - startTime) / 1000.0;
			setText(&quot;Time: &quot; + seconds + &quot; sec.&quot;);
		}
	}

	public void mouseReleased(MouseEvent evt) { }
	public void mouseClicked(MouseEvent evt) { }
	public void mouseEntered(MouseEvent evt) { }
	public void mouseExited(MouseEvent evt) { }

}</code></pre>
</blockquote>
<h2 id="Unit8">Unit 8</h2>
<p>
	There was ... no reading material for this week.
	That caught me off-guard.
	Given the discussion question for the week, which asked about the advantages of Java in creating a per-customer look and feel for an application, I was sure we&apos;d cover something about that this week.
	I guess the real advantage is Java&apos;s modularity, or rather, the ability to create modular applications in Java.
	As we covered last week, multiple views can be set up for the same model and controller.
	Simply swapping out the view allows one to create an entirely different look and feel for their application without changing any of the back-end logic.
</p>
<p>
	One student severely disappointed me when I was grading their work from last week.
	They couldn&apos;t seem to get their Web server to function with a real Web browser.
	So what did they do?
	Instead of trying to bebug the server, which was obviously the problem, they assumed the problem was the Web browser.
	They built their own client and used that to test the Web server.
	Obviously, the server wasn&apos;t functional and wasn&apos;t using actual <abbr title="Hypertext Transfer Protocol">HTTP</abbr>, so because the browser <strong>*was*</strong> using <abbr title="Hypertext Transfer Protocol">HTTP</abbr>, the two were incompatible.
	Replacing the client fixed this because then both client and server were speaking some non-<abbr title="Hypertext Transfer Protocol">HTTP</abbr> language based on <abbr title="Hypertext Transfer Protocol">HTTP</abbr>.
	It took me a bit to debug their code and figure out what was going on.
	The problem was Windows-specific though, so it would&apos;ve worked fine on my machine.
	However, the code serves files from the root of the file system, not the document root.
	Every file on the file system was exposed, if readable by the server!
	That&apos;s where the real issue came in, too: Windows file paths don&apos;t start with a slash, but <abbr title="Hypertext Transfer Protocol">HTTP</abbr> file paths <strong>*always*</strong> start with a slash.
	The client they wrote was sending malformed paths, paths that Windows could understand but that were invalid for use in <abbr title="Hypertext Transfer Protocol">HTTP</abbr>.
</p>
<p>
	The learning journal task for this week asked us to add all the items from the lower tool bar in a menu in the menu bar.
	There was only one item though.
	I&apos;m hoping there isn&apos;t some strange issue with my setup, and that I&apos;ve done this right.
	I added code to add all tool bar items to the menu, so if more than one item actually existed, it would be added.
	Only that one item showed up though, as it was the only one in the tool bar.
	A later step said that two of the menu items were the only two without icons, but <strong>*none*</strong> of the menu items had icons.
	It was time to debug.
	After at least an hour of fiddling with it, I finally got Eclipse to recognise the resource files, which it had been ignoring.
	I&apos;d added them and refreshed the project before, but that wasn&apos;t enough.
	I&apos;m not sure what Eclipse&apos;s deal is, but it&apos;s really stupid about file detection.
	Once it finally found the files, the icons showed up, and the missing toolbar items showed up, both on the toolbar and in the menu.
	In the end, the files were in the exact place I put them to start with, but Eclipse now included them in the compiled output.
</p>
<p>
	For the quote, I decided to write a free-form poem of my own.
	The poem got a bit long though, and I couldn&apos;t find a segment I liked well enough out of context.
	It was a poem I&apos;ve been meaning to write for a while though, so it was still time well-spent.
	I ended up taking a quote from a Kellee Maize song: <a href="https://kelleemaize.com/songs/yesterday">Yesterday</a>.
	Her licensing is a bit inconsistent, so depending on where you get her work, it may or may not be under a free license.
	There is a place to get that particular song <a href="https://kelleemaize.bandcamp.com/track/yesterday">under <abbr title="Creative Commons Attribution-ShareAlike 3.0 Unported">CC BY-SA 3.0</abbr></a> though.
</p>
<p>
	With all the required work out of the way, I went through and added a bunch of <code>serialVersionUID</code> properties to the classes in the three files I edited.
	Eclipse complains about these properties being missing.
	Since we were instructed to customise our programs a bit, I also changed every instance of the word &quot;Color&quot; in the interface to be &quot;Colour&quot;.
	I live in the United States, but I usually type with a British accent.
</p>
<p>
	The project instructions warned us there would be compile warnings.
	This is likely because of all the missing <code>serialVersionUID</code> properties throughout the code we started with.
	However, instead of warnings, I got an outright error.
	It claimed a bunch of the resources didn&apos;t exist, so the compilation had failed.
	A <abbr title="Java Archive">JAR</abbr> file was still created though.
	I tried executing it, and it seemed to work just fine.
	The resources are intact and the software runs as expected.
	I&apos;m not sure what the actual issue is; I don&apos;t think there is one.
</p>
<h3>Learning journal exercise</h3>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package guidemo;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.*;

/**
 * A frame that displays a multiline text, possibly with a background image
 * and with added icon images, in a DrawPanel, along with a variety of controls.
 */
public class GuiDemo extends JFrame{
	
/**
 * Adding this property gets Eclipse to quit complaining.
 */
	private static final long serialVersionUID = 0;

/**
 * The main program just creates a GuiDemo frame and makes it visible.
 */
	public static void main(String[] args){
		JFrame frame = new GuiDemo();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	private DrawPanel drawPanel;
	private SimpleFileChooser fileChooser;
	private TextMenu textMenu;
	private JCheckBoxMenuItem gradientOverlayCheckbox = new JCheckBoxMenuItem(&quot;Gradient Overlay&quot;, true);
	
/**
 * The constructor creates the frame, sizes it, and centres it horizontally on the screen.
 */
	public GuiDemo() {
		
		super(&quot;Sayings&quot;);  // Specifies the string for the title bar of the window.
		JPanel content = new JPanel();  // To hold the content of the window.
		content.setBackground(Color.LIGHT_GRAY);
		content.setLayout(new BorderLayout());
		setContentPane(content);
		
// Create the DrawPanel that fills most of the window, and customise it.
		
		drawPanel = new DrawPanel();
		drawPanel.getTextItem().setText(
				&quot;      Wasted visions of purity\n&quot; +
				&quot;Salvation isn&apos;t found in the majority\n&quot; +
				&quot;      Collect my values in my purse\n&quot; +
				&quot;I bore my soul with each new verse\n&quot; +
				&quot;\n&quot; +
				&quot;~ Kellee Maize (CC BY-SA 3.0)\n&quot; +
				&quot;  &lt;https://kelleemaize.com/&gt;&quot;
			);
		drawPanel.getTextItem().setFontSize(36);
		drawPanel.getTextItem().setJustify(TextItem.LEFT);
		drawPanel.setBackgroundImage(Util.getImageResource(&quot;resources/images/eagle_nebula.jpeg&quot;));
		content.add(drawPanel, BorderLayout.CENTER);
		
// Add an icon toolbar to the SOUTH position of the layout
		
		IconSupport iconSupport = new IconSupport(drawPanel);
		content.add( iconSupport.createToolbar(true), BorderLayout.SOUTH );
		content.add(makeToolbar(), BorderLayout.NORTH);
		
// Create the menu bar and add it to the frame.  The TextMenu is defined by
// a separate class.  The other menus are created in this class.
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.add(makeFileMenu());
		textMenu = new TextMenu(drawPanel);
		menuBar.add(textMenu);
		menuBar.add(makeBackgroundMenu());
		menuBar.add(iconSupport.createMenu());
		setJMenuBar(menuBar);
		
// Set the size of the window and its position.
		
		pack();  // Size the window to fit its content.
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation((screenSize.width - getWidth())/2, 50);
		
// Create and customise the file chooser that is used for file operations.
		
		fileChooser = new SimpleFileChooser();
		try { // I&apos;d like to use the Desktop folder as the initial folder in the file chooser.
			String userDir = System.getProperty(&quot;user.home&quot;);
			if (userDir != null) {
				File desktop = new File(userDir,&quot;Desktop&quot;);
				if (desktop.isDirectory())
					fileChooser.setDefaultDirectory(desktop);
			}
		}
		catch (Exception e) {
		}

	} // end constructor
	
/**
 * Create the &quot;File&quot; menu from actions that are defined later in this class.
 */
	private JMenu makeFileMenu() {
		JMenu menu = new JMenu(&quot;File&quot;);
		menu.add(newPictureAction);
		menu.add(saveImageAction);
		menu.addSeparator();
		menu.add(quitAction);
		return menu;
	}
	
/**
 * Create the &quot;Background&quot; menu, using objects of type ChooseBackgroundAction,
 * a class that is defined later in this file.
 */
	private JMenu makeBackgroundMenu() {
		JMenu menu = new JMenu(&quot;Background&quot;);
		menu.add(new ChooseBackgroundAction(&quot;Mandelbrot&quot;));
		menu.add(new ChooseBackgroundAction(&quot;Earthrise&quot;));
		menu.add(new ChooseBackgroundAction(&quot;Sunset&quot;));
		menu.add(new ChooseBackgroundAction(&quot;Cloud&quot;));
		menu.add(new ChooseBackgroundAction(&quot;Eagle_nebula&quot;));
		menu.addSeparator();
		menu.add(new ChooseBackgroundAction(&quot;Custom...&quot;));
		menu.addSeparator();
		menu.add(new ChooseBackgroundAction(&quot;Colour...&quot;));
		menu.addSeparator();
		menu.add(gradientOverlayCheckbox);
		gradientOverlayCheckbox.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				if (gradientOverlayCheckbox.isSelected())
					drawPanel.setGradientOverlayColor(Color.WHITE);
				else
					drawPanel.setGradientOverlayColor(null);
			}
		});
		return menu;
	}
	
/**
 * This method constructs the main toolbar.
 * 
 * @return The main toolbar
 */
	public JToolBar makeToolbar() {
		JToolBar toolbar = new JToolBar();
		toolbar.add(new ChooseBackgroundAction(&quot;Mandelbrot&quot;));
		toolbar.add(new ChooseBackgroundAction(&quot;Earthrise&quot;));
		toolbar.add(new ChooseBackgroundAction(&quot;Sunset&quot;));
		toolbar.add(new ChooseBackgroundAction(&quot;Cloud&quot;));
		toolbar.add(new ChooseBackgroundAction(&quot;Eagle_nebula&quot;));
		toolbar.addSeparator();
		toolbar.add(new ChooseBackgroundAction(&quot;Custom...&quot;));
		toolbar.addSeparator();
		toolbar.add(new ChooseBackgroundAction(&quot;Colour...&quot;));
		toolbar.addSeparator();
		toolbar.add(newPictureAction);
		toolbar.add(saveImageAction);
		return toolbar;
	}
	
	private AbstractAction newPictureAction = 
		new AbstractAction(&quot;New&quot;, Util.iconFromResource(&quot;resources/action_icons/fileopen.png&quot;)) {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
			private static final long serialVersionUID = 0;

			public void actionPerformed(ActionEvent evt) {
				drawPanel.clear();
				gradientOverlayCheckbox.setSelected(true);
				textMenu.setDefaults();
			}
		};
	
	private AbstractAction quitAction = 
		new AbstractAction(&quot;Quit&quot;, Util.iconFromResource(&quot;resources/action_icons/exit.png&quot;)) {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
			private static final long serialVersionUID = 0;

			public void actionPerformed(ActionEvent evt) {
				System.exit(0);
			}
		};
		
	private AbstractAction saveImageAction = 
		new AbstractAction(&quot;Save Image...&quot;, Util.iconFromResource(&quot;resources/action_icons/filesave.png&quot;)) {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
			private static final long serialVersionUID = 0;

			public void actionPerformed(ActionEvent evt) {
				File f = fileChooser.getOutputFile(drawPanel, &quot;Select Ouput File&quot;, &quot;saying.jpeg&quot;);
				if (f != null) {
					try {
						BufferedImage img = drawPanel.copyImage();
						String format;
						String fileName = f.getName().toLowerCase();
						if (fileName.endsWith(&quot;.png&quot;))
							format = &quot;PNG&quot;;
						else if (fileName.endsWith(&quot;.jpeg&quot;) || fileName.endsWith(&quot;.jpg&quot;))
							format = &quot;JPEG&quot;;
						else {
							JOptionPane.showMessageDialog(drawPanel,
									&quot;The output file name must end wth\n.png or .jpeg.&quot;);
							return;
						}
						ImageIO.write(img,format,f);
					}
					catch (Exception e) {
						JOptionPane.showMessageDialog(drawPanel, &quot;Sorry, the image could not be saved.&quot;);
					}
				}
			}
		};
	
	
/**
 * An object of type ChooseBackgroudnAction represents an action through which the
 * user selects the background of the picture.  There are three types of background:
 * solid colour background (&quot;Colour...&quot; command), an image selected by the user from 
 * the file system (&quot;Custom...&quot; command), and four built-in image resources
 * (Mandelbrot, Earthrise, Sunset, and Eagle_nebula).
 */
	private class ChooseBackgroundAction extends AbstractAction {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
		private static final long serialVersionUID = 0;

		String text;
		ChooseBackgroundAction(String text) {
			super(text);
			this.text = text;
			if (!text.equals(&quot;Custom...&quot;) &amp;&amp; !text.equals(&quot;Colour...&quot;)) {
				putValue(Action.SMALL_ICON, 
						Util.iconFromResource(&quot;resources/images/&quot; + text.toLowerCase() + &quot;_thumbnail.jpeg&quot;));
			}
			if (text.equals(&quot;Colour...&quot;)) {
				putValue(Action.SHORT_DESCRIPTION, &quot;&lt;html&gt;Use a solid color for background&lt;br&gt;instead of an image.&lt;/html&gt;&quot;);
				BufferedImage icon = new BufferedImage(32, 32, BufferedImage.TYPE_INT_RGB);
				Graphics g = icon.createGraphics();
				g.setColor(Color.DARK_GRAY);
				g.fillRect(0,0,32,32);
				g.setColor(Color.RED);
				g.fillRect(4,13,16,16);
				g.setColor(Color.GREEN);
				g.fillRect(6,4,16,16);
				g.setColor(Color.BLUE);
				g.fillRect(12,11,16,16);
				g.dispose();
				putValue(Action.SMALL_ICON, new ImageIcon(icon));
			} else if (text.equals(&quot;Custom...&quot;)) {
				putValue(Action.SHORT_DESCRIPTION, &quot;&lt;html&gt;Select an image file&lt;br&gt;to use as the background.&lt;/html&gt;&quot;);
				putValue(Action.SMALL_ICON, 
						Util.iconFromResource(&quot;resources/action_icons/fileopen.png&quot;));
			} else
				putValue(Action.SHORT_DESCRIPTION, &quot;Use this image as the background.&quot;);
				
		}
		public void actionPerformed(ActionEvent evt) {
			if (text.equals(&quot;Custom...&quot;)) {
				File inputFile = fileChooser.getInputFile(drawPanel, &quot;Select Background Image&quot;);
				if (inputFile != null) {
					try {
						BufferedImage img = ImageIO.read(inputFile);
						if (img == null)
							throw new Exception();
						drawPanel.setBackgroundImage(img);
					}
					catch (Exception e) {
						JOptionPane.showMessageDialog(drawPanel, &quot;Sorry, couldn&apos;t read the file.&quot;);
					}
				}
			}
			else if (text.equals(&quot;Colour...&quot;)) {
				Color c = JColorChooser.showDialog(drawPanel, &quot;Select Colour for Background&quot;, drawPanel.getBackground());
				if (c != null) {
					drawPanel.setBackground(c);
					drawPanel.setBackgroundImage(null);
				}
			}
			else {
				Image bg = Util.getImageResource(&quot;resources/images/&quot; + text.toLowerCase() + &quot;.jpeg&quot;);
				drawPanel.setBackgroundImage(bg);
			}
		}
	}
}</code></pre>
</blockquote>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package guidemo;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;
import java.util.ArrayList;

/**
 * Contains a set of Actions that can be used to select images that can
 * be added to a DrawPanel (in the form of ImageItems).  Can create a
 * toolbar containing a button for each Action in the set.  A button
 * shows an ImageIcon with the image that is selected by that button.
 * Clicking one of the buttons also sets the cursor in the DrawPanel
 * to be a (rough) copy of the image.
 */
public class IconSupport {
	
	private DrawPanel panel;
	private ArrayList&lt;BufferedImage&gt; iconImages = new ArrayList&lt;BufferedImage&gt;();
	private ArrayList&lt;Action&gt; actions = new ArrayList&lt;Action&gt;();

/**
 * This method constructs the menu that allows the choosing of a stamper.
 * 
 * @return A stamper menu
 */
	public JMenu createMenu() {
		JMenu stamper = new JMenu(&quot;Stamper&quot;);
		for(Action a : actions) {
			stamper.add(a);
		}
		return stamper;
	}

	public IconSupport(DrawPanel owner) {
		panel = owner;
		String[] iconNames = {&quot;bell&quot;, &quot;camera&quot;, &quot;flower&quot;, &quot;star&quot;, &quot;check&quot;, &quot;crossout&quot;, 
				 &quot;tux&quot;, &quot;bomb&quot;, &quot;keyboard&quot;,&quot;lightbulb&quot;, &quot;tv&quot;};
		for (String name : iconNames) {
			BufferedImage img = Util.getBufferedImageResource(&quot;resources/icons/&quot; + name + &quot;.png&quot;);
			if (img != null) {
				iconImages.add(img);
				actions.add(new SelectIconAction(name,iconImages.size()-1));
			}
		}
		actions.add(new NoIconAction());
	}
	
/**
 * Return a toolbar containing buttons representing the images that can be added
 * to the DrawPanel.
 * @param horizontal  a value of JToolBar.HORIZONTAL or JToolBar.VERTICAL tells
 * whether the toolbar is meant to have horizontal or vertical orientation.
 */
	public JToolBar createToolbar(boolean horizontal) {
		JToolBar tbar = new JToolBar( horizontal? JToolBar.HORIZONTAL : JToolBar.VERTICAL);
		for (int i = 0; i &lt; actions.size() - 1; i++)
			tbar.add(actions.get(i));
		tbar.addSeparator(new Dimension(15,0));
		tbar.add(actions.get(actions.size()-1));
		return tbar;
	}
	
	private class NoIconAction extends AbstractAction {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
		private static final long serialVersionUID = 0;

		NoIconAction() {
			super(&quot;Eraser&quot;);
			BufferedImage del = new BufferedImage(32,32,BufferedImage.TYPE_INT_ARGB);
			Graphics g = del.createGraphics();
			g.setColor(Color.WHITE);
			g.fillRect(0,0,32,32);
			g.setColor(Color.RED);
			g.drawString(&quot;DEL&quot;,5,20);
			g.dispose();
			putValue(Action.SMALL_ICON, new ImageIcon(del));
			putValue(Action.SHORT_DESCRIPTION, &quot;Use Mouse to Erase Icons&quot;); // tooltip
		}
		public void actionPerformed(ActionEvent evt) {
			panel.setCurrentDrawImage(null);
			panel.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
		}
	}
	
	private class SelectIconAction extends AbstractAction {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
		private static final long serialVersionUID = 0;

		int iconNumber;
		SelectIconAction(String name, int n) {
			   // Note: The name is suppressed in toolbars, but not in menus.
			super(name,new ImageIcon(iconImages.get(n)));
			iconNumber = n;
			putValue(Action.SHORT_DESCRIPTION, &quot;Use Mouse to Stamp this Icon&quot;); // tooltip
		}
		public void actionPerformed(ActionEvent evt) {
			BufferedImage image = iconImages.get(iconNumber);
			panel.setCurrentDrawImage(image);
			Cursor c = Util.createImageCursor(image, image.getWidth()/2, image.getHeight()/2);
			panel.setCursor(c);
		}
	}
}</code></pre>
</blockquote>
<blockquote>
<pre><code>/* 
 * Copyright (C) 2017 Alex Yst
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package guidemo;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;;

/**
 * A menu full of commands that affect the text shown
 * in a DrawPanel.
 */
public class TextMenu extends JMenu {
/**
 * Adding this property gets Eclipse to quit complaining.
 */
	private static final long serialVersionUID = 0;

	private final DrawPanel panel;    // the panel whose text is controlled by this menu

	private JCheckBoxMenuItem bold;   // controls whether the text is bold or not.
	private JCheckBoxMenuItem italic; // controls whether the text is italic or not.
/**
 * Calling left.setSelected(), passing in a boolean true, can be used to reset
 * the justification menu&apos;s selection. PLEASE NOTE THAT THIS PROBABLY WON&apos;T
 * RESET THE ACTUAL JUSTIFICATION IF IT HASN&apos;T BEEN RESET ALREADY.
 */
	private JRadioButtonMenuItem left;
	
/**
 * Constructor creates all the menu commands and adds them to the menu.
 * @param owner the panel whose text will be controlled by this menu.
 */
	public TextMenu(DrawPanel owner) {
		super(&quot;Text&quot;);
		this.panel = owner;
		final JMenuItem change = new JMenuItem(&quot;Change Text...&quot;);
		change.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				String currentText = panel.getTextItem().getText();
				String newText = GetTextDialog.showDialog(panel,currentText);
				if (newText != null &amp;&amp; newText.trim().length() &gt; 0) {
					panel.getTextItem().setText(newText);
					panel.repaint();
				}
			}
		});
		final JMenuItem size = new JMenuItem(&quot;Set Size...&quot;);
		size.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				int currentSize = panel.getTextItem().getFontSize();
				String s = JOptionPane.showInputDialog(panel, &quot;What font size do you want to use?&quot;,currentSize);
				if (s != null &amp;&amp; s.trim().length() &gt; 0) {
					try {
						int newSize = Integer.parseInt(s.trim()); // can throw NumberFormatException
						panel.getTextItem().setFontSize(newSize); // can throw IllegalArgumentException
						panel.repaint();
					}
					catch (Exception e) {
						JOptionPane.showMessageDialog(panel, s + &quot; is not a legal text size.\n&quot;
								+&quot;Please enter a positive integer.&quot;);
					}
				}
			}
		});
		final JMenuItem color = new JMenuItem(&quot;Set Color...&quot;);
		color.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				Color currentColor = panel.getTextItem().getColor();
				Color newColor = JColorChooser.showDialog(panel, &quot;Select Text Color&quot;, currentColor);
				if (newColor != null) {
					panel.getTextItem().setColor(newColor);
					panel.repaint();
				}
			}
		});
		final JMenuItem lineHeight = new JMenuItem(&quot;Set Line Height...&quot;);
		lineHeight.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				TextItem textItem = panel.getTextItem();
				double currentHeight = textItem.getLineHeightMultiplier();
				String s = JOptionPane.showInputDialog(panel, &quot;What line height multiplier do you want to use?&quot;, currentHeight);
				if (s != null &amp;&amp; s.trim().length() &gt; 0) {
					try {
						double newHeight = Double.parseDouble(s.trim());
						textItem.setLineHeightMultiplier(newHeight);
						panel.repaint();
					}
					catch (Exception e) {
						JOptionPane.showMessageDialog(panel, s + &quot; is not a legal line height multiplier.\n&quot;
								+&quot;Please enter a non-negative number.&quot;);
					}
				}
			}
		});
		italic = new JCheckBoxMenuItem(&quot;Italic&quot;);
		italic.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				panel.getTextItem().setItalic(italic.isSelected());
				panel.repaint();
			}
		});
		bold = new JCheckBoxMenuItem(&quot;Bold&quot;);
		bold.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				panel.getTextItem().setBold(bold.isSelected());
				panel.repaint();
			}
		});
		add(change);
		addSeparator();
		add(size);
		add(color);
		add(lineHeight);
		add(italic);
		add(bold);
		addSeparator();
		add(makeFontNameSubmenu());
		add(makeJustifyMenu());
	}
	
/**
 * Reset the state of the menu to reflect the default settings for text
 * in a DrawPanel.  (Sets the italic and bold checkboxes to unselected.)
 * This method is called by the main program when the user selects the
 * &quot;New&quot; command, to make sure that the menu state reflects the contents
 * of the panel.
 */
	public void setDefaults() {
		italic.setSelected(false);
		bold.setSelected(false);
		left.setSelected(true);
	}
	
/**
 * Create a menu containing a list of all available fonts.
 * (It turns out this can be very messy, at least on Linux, but
 * it does show the use what is available and lets the user try
 * everything!)
 */
	private JMenu makeFontNameSubmenu() {
		ActionListener setFontAction = new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				panel.getTextItem().setFontName(evt.getActionCommand());
				panel.repaint();
			}
		};
		JMenu menu = new JMenu(&quot;Font Name&quot;);
		String[] basic = { &quot;Serif&quot;, &quot;SansSerif&quot;, &quot;Monospace&quot; };
		for (String f : basic) {
			JMenuItem m = new JMenuItem(f+ &quot; Default&quot;);
			m.setActionCommand(f);
			m.addActionListener(setFontAction);
			m.setFont(new Font(f,Font.PLAIN,12));
			menu.add(m);
		}
		menu.addSeparator();
		String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
		if (fonts.length &lt;= 20) {
			for (String f : fonts) {
				JMenuItem m = new JMenuItem(f);
				m.addActionListener(setFontAction);
				m.setFont(new Font(f,Font.PLAIN,12));
				menu.add(m);
			}
		}
		else { //Too many items for one menu; divide them into several sub-sub-menus.
			char ch1 = &apos;A&apos;;
			char ch2 = &apos;A&apos;;
			JMenu m = new JMenu();
			int i = 0;
			while (i &lt; fonts.length) {
				while (i &lt; fonts.length &amp;&amp; (Character.toUpperCase(fonts[i].charAt(0)) &lt;= ch2 || ch2 == &apos;Z&apos;)) {
					JMenuItem item = new JMenuItem(fonts[i]);
					item.addActionListener(setFontAction);
					item.setFont(new Font(fonts[i],Font.PLAIN,12));
					m.add(item);
					i++;
				}
				if (i == fonts.length || (m.getMenuComponentCount() &gt;= 12 &amp;&amp; i &lt; fonts.length-4)) {
					if (ch1 == ch2)
						m.setText(&quot;&quot; + ch1);
					else
						m.setText(ch1 + &quot; to &quot; + ch2);
					menu.add(m);
					if (i &lt; fonts.length)
						m = new JMenu();
					ch2++;
					ch1 = ch2;
				}
				else 
					ch2++;
			}
		}
		return menu;
	}

/**
 * This method constructs the justification submenu.
 * 
 * @return A text-justification submenu
 */
	public JMenu makeJustifyMenu() {
		left = new JRadioButtonMenuItem(&quot;Left&quot;);
		JRadioButtonMenuItem right = new JRadioButtonMenuItem(&quot;Right&quot;);
		JRadioButtonMenuItem centre = new JRadioButtonMenuItem(&quot;Centre&quot;);
		JMenu menu = new JMenu(&quot;Justify&quot;);
		menu.add(left);
		menu.add(right);
		menu.add(centre);
		ButtonGroup group = new ButtonGroup();
		group.add(left);
		group.add(right);
		group.add(centre);
		left.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.getTextItem().setJustify(TextItem.LEFT);
				panel.repaint();
			}
		});
		right.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.getTextItem().setJustify(TextItem.RIGHT);
				panel.repaint();
			}
		});
		centre.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				panel.getTextItem().setJustify(TextItem.CENTER);
				panel.repaint();
			}
		});
		left.setSelected(true);
		return menu;
	}
}</code></pre>
</blockquote>
		<hr/>
		<p>
			Copyright © 2017 Alex Yst;
			You may modify and/or redistribute this document under the terms of the <a rel="license" href="/license/gpl-3.0-standalone.xhtml"><abbr title="GNU&apos;s Not Unix">GNU</abbr> <abbr title="General Public License version Three or later">GPLv3+</abbr></a>.
			If for some reason you would prefer to modify and/or distribute this document under other free copyleft terms, please ask me via email.
			My address is in the source comments near the top of this document.
			This license also applies to embedded content such as images.
			For more information on that, see <a href="/en/a/licensing.xhtml">licensing</a>.
		</p>
		<p>
			<abbr title="World Wide Web Consortium">W3C</abbr> standards are important.
			This document conforms to the <a href="https://validator.w3.org./nu/?doc=https%3A%2F%2Fy.st.%2Fen%2Fcoursework%2FCS1103%2F"><abbr title="Extensible Hypertext Markup Language">XHTML</abbr> 5.1</a> specification and uses style sheets that conform to the <a href="http://jigsaw.w3.org./css-validator/validator?uri=https%3A%2F%2Fy.st.%2Fen%2Fcoursework%2FCS1103%2F"><abbr title="Cascading Style Sheets">CSS</abbr>3</a> specification.
		</p>
	</body>
</html>

